blob: b31587f69c6133edadd1b1dd47ced08c33112492 [file] [log] [blame]
// 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 = 7, 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 */
};
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",
};
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();
}