121 lines
2.7 KiB
C
121 lines
2.7 KiB
C
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
|
// Copyright 2022 IBM Corp.
|
|
|
|
#define pr_fmt(fmt) "PLDM: " fmt
|
|
|
|
#include <cpu.h>
|
|
#include <opal.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "pldm.h"
|
|
|
|
/*
|
|
* PLDM over MCTP (DSP0241)
|
|
*
|
|
* First byte of the MCTP message is the message Type = PLDM
|
|
* PLDM = 0x01 (000_0001b)
|
|
*
|
|
* Next bytes of the MCTP message (MCTP message body) contain the
|
|
* PLDM message (The base PLDM message fields are defined in DSP0240)
|
|
*/
|
|
|
|
int pldm_mctp_message_tx(struct pldm_tx_data *tx)
|
|
{
|
|
tx->mctp_msg_type = MCTP_MSG_TYPE_PLDM;
|
|
|
|
return ast_mctp_message_tx(tx->tag_owner, tx->msg_tag,
|
|
&tx->mctp_msg_type,
|
|
tx->data_size + sizeof(tx->mctp_msg_type));
|
|
}
|
|
|
|
int pldm_mctp_message_rx(uint8_t eid, bool tag_owner, uint8_t msg_tag,
|
|
const uint8_t *buf, int len)
|
|
{
|
|
struct pldm_rx_data *rx;
|
|
int rc = 0;
|
|
|
|
rx = zalloc(sizeof(struct pldm_rx_data));
|
|
if (!rx) {
|
|
prlog(PR_ERR, "failed to allocate rx message\n");
|
|
return OPAL_NO_MEM;
|
|
}
|
|
|
|
rx->msg = (struct pldm_msg *)buf;
|
|
rx->source_eid = eid;
|
|
rx->msg_len = len;
|
|
rx->tag_owner = tag_owner;
|
|
rx->msg_tag = msg_tag;
|
|
|
|
/* Additional header information */
|
|
if (unpack_pldm_header(&rx->msg->hdr, &rx->hdrinf)) {
|
|
prlog(PR_ERR, "%s: unable to decode header\n", __func__);
|
|
rc = OPAL_EMPTY;
|
|
goto out;
|
|
}
|
|
|
|
switch (rx->hdrinf.msg_type) {
|
|
case PLDM_RESPONSE:
|
|
rc = pldm_requester_handle_response(rx);
|
|
break;
|
|
case PLDM_REQUEST:
|
|
rc = pldm_responder_handle_request(rx);
|
|
break;
|
|
default:
|
|
prlog(PR_ERR, "%s: message not supported (msg type: 0%x)\n",
|
|
__func__, rx->hdrinf.msg_type);
|
|
rc = OPAL_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
out:
|
|
free(rx);
|
|
return rc;
|
|
}
|
|
|
|
int pldm_mctp_init(void)
|
|
{
|
|
int nbr_elt = 8, rc = OPAL_SUCCESS;
|
|
|
|
int (*pldm_config[])(void) = {
|
|
ast_mctp_init, /* MCTP Binding */
|
|
pldm_responder_init, /* Register mandatory commands we'll respond to */
|
|
pldm_requester_init, /* Requester implementation */
|
|
pldm_base_get_tid_req, /* Get BMC tid */
|
|
pldm_platform_init, /* Get PDRs data */
|
|
pldm_bios_init, /* Get Bios data */
|
|
pldm_fru_init, /* Get Fru data */
|
|
pldm_file_io_init, /* Get FILE IO data */
|
|
};
|
|
|
|
const char *pldm_config_error[] = {
|
|
"Failed to bind MCTP",
|
|
"Failed to register mandatory commands",
|
|
"Failed to configure requister",
|
|
"Failed to retrieve BMC Tid",
|
|
"Failed to retrieve Data Records",
|
|
"Failed to retrieve Bios data",
|
|
"Failed to retrieve Fru data",
|
|
"Failed to retrieve File io data",
|
|
};
|
|
|
|
prlog(PR_NOTICE, "%s - Getting PLDM data\n", __func__);
|
|
|
|
for (int i = 0; i < nbr_elt; i++) {
|
|
rc = pldm_config[i]();
|
|
if (rc) {
|
|
prlog(PR_ERR, "%s\n", pldm_config_error[i]);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
out:
|
|
prlog(PR_NOTICE, "%s - done, rc: %d\n", __func__, rc);
|
|
return rc;
|
|
}
|
|
|
|
void pldm_mctp_exit(void)
|
|
{
|
|
pldm_platform_exit();
|
|
|
|
ast_mctp_exit();
|
|
}
|