in meta-facebook/yv35-bb/src/ipmi/plat_ipmi.c [451:531]
void pal_OEM_1S_MSG_OUT(ipmi_msg *msg)
{
uint8_t target_IF;
ipmb_error status;
ipmi_msg *bridge_msg;
if (msg->completion_code != CC_INVALID_IANA) {
msg->completion_code = CC_SUCCESS;
}
if (msg->data_len <= 2) { // Should input target, netfn, cmd
msg->completion_code = CC_INVALID_LENGTH;
}
target_IF = msg->data[0];
// To do: send SEL to another BMC
if (target_IF == PEER_BMC_IPMB_IFs) {
if (msg->InF_source == SLOT1_BIC_IFs) {
target_IF = SLOT3_BIC_IFs;
} else if (msg->InF_source == SLOT3_BIC_IFs) {
target_IF = SLOT1_BIC_IFs;
} else {
msg->completion_code = CC_INVALID_DATA_FIELD;
}
}
if ((IPMB_config_table[IPMB_inf_index_map[target_IF]].Inf == Reserve_IFs) ||
(IPMB_config_table[IPMB_inf_index_map[target_IF]].EnStatus ==
Disable)) { // Bridge to invalid or disabled interface
printf("OEM_MSG_OUT: Invalid bridge interface: %x\n", target_IF);
msg->completion_code = CC_NOT_SUPP_IN_CURR_STATE;
}
if (msg->completion_code == CC_SUCCESS) { // only send to target while msg is valid
bridge_msg = (ipmi_msg *)malloc(sizeof(ipmi_msg));
if (bridge_msg == NULL) {
msg->completion_code = CC_OUT_OF_SPACE;
} else {
memset(bridge_msg, 0, sizeof(ipmi_msg));
if (DEBUG_IPMI) {
printf("bridge targetIf %x, len %d, netfn %x, cmd %x\n", target_IF,
msg->data_len, msg->data[1] >> 2, msg->data[2]);
}
bridge_msg->data_len = msg->data_len - 3;
bridge_msg->seq_source = msg->seq_source;
bridge_msg->InF_target = msg->data[0];
bridge_msg->InF_source = msg->InF_source;
bridge_msg->netfn = msg->data[1] >> 2;
bridge_msg->cmd = msg->data[2];
if (bridge_msg->data_len != 0) {
memcpy(&bridge_msg->data[0], &msg->data[3],
bridge_msg->data_len * sizeof(msg->data[0]));
}
status = ipmb_send_request(bridge_msg, IPMB_inf_index_map[target_IF]);
if (status != ipmb_error_success) {
printf("OEM_MSG_OUT send IPMB req fail status: %x", status);
msg->completion_code = CC_BRIDGE_MSG_ERR;
}
free(bridge_msg);
}
}
if (msg->completion_code !=
CC_SUCCESS) { // Return to source while data is invalid or sending req to Tx task fail
msg->data_len = 0;
status = ipmb_send_response(msg, IPMB_inf_index_map[msg->InF_source]);
if (status != ipmb_error_success) {
printf("OEM_MSG_OUT send IPMB resp fail status: %x", status);
}
}
return;
}