1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <console/console.h>
4 #include <drivers/ipmi/ipmi_if.h>
8 static int ipmi_add_sel_entry(int port
, unsigned char *data
, int size
)
10 return ipmi_message(port
, IPMI_NETFN_STORAGE
, 0, IPMI_ADD_SEL_ENTRY
, data
, size
,
14 void ipmi_send_to_bmc(unsigned char *data
, size_t size
)
16 if (CONFIG(IPMI_KCS
)) {
17 _Static_assert(CONFIG_BMC_KCS_BASE
!= 0,
18 "\tBMC_ERROR: Unable to send record: Port #:0\n");
20 ipmi_add_sel_entry(CONFIG_BMC_KCS_BASE
, data
, size
);
24 void ipmi_send_sel_iio_err(uint8_t iio_stack_num
, uint8_t err_id
)
26 struct ipmi_sel_iio_err ubslp
= {
27 .record_id
= SEL_RECORD_ID
,
28 .record_type
= CONFIG_RAS_SEL_VENDOR_ID
,
29 .general_info
= SEL_PCIE_IIO_ERR
,
30 .iio_stack_num
= iio_stack_num
,
34 ipmi_send_to_bmc((unsigned char *)&ubslp
, sizeof(ubslp
));
35 printk(BIOS_DEBUG
, "\tsending PCIE IIO device error record to BMC\n");
36 printk(BIOS_DEBUG
, "\tstack # = %x\n", ubslp
.iio_stack_num
);
39 void ipmi_send_sel_pcie_dev_err(pci_devfn_t bdf
, uint16_t prmry_cnt
, uint8_t sec_id
,
42 struct pci_dev_fn
*inbdf
= (struct pci_dev_fn
*)&bdf
;
43 struct ipmi_sel_pcie_dev_err ubslp
= {
44 .record_id
= SEL_RECORD_ID
,
45 .record_type
= CONFIG_RAS_SEL_VENDOR_ID
,
46 .general_info
= SEL_PCIE_DEV_ERR
,
47 .timestamp
= 0, /* BMC will apply timestamp */
49 .bdf
.bus
= inbdf
->bus
,
50 .bdf
.dev
= inbdf
->dev
,
51 .bdf
.func
= inbdf
->func
>> 12,
52 .primary_err_count
= prmry_cnt
,
53 .primary_id
= prmry_id
,
54 .secondary_id
= sec_id
,
57 ipmi_send_to_bmc((unsigned char *)&ubslp
, sizeof(ubslp
));
58 printk(BIOS_DEBUG
, "\tsending PCIE device error record to BMC\n");
59 printk(BIOS_DEBUG
, "\tbdf = %x:%x:%x\n", ubslp
.bdf
.bus
, ubslp
.bdf
.dev
, ubslp
.bdf
.func
);
60 printk(BIOS_DEBUG
, "\tubslp.primary_id = %x\n", ubslp
.primary_id
);
61 printk(BIOS_DEBUG
, "\tsecondary_id = %x\n", ubslp
.secondary_id
);
64 void ipmi_send_sel_pcie_dev_fail(uint16_t sts_reg
, uint16_t src_id
, enum fail_type code
)
66 struct ipmi_sel_pcie_dev_fail ubslp
= {
67 .record_id
= SEL_RECORD_ID
,
68 .record_type
= CONFIG_RAS_SEL_VENDOR_ID
,
69 .general_info
= SEL_PCIE_DEV_FAIL_ID
,
70 .timestamp
= 0, /* BMC will apply timestamp */
72 .failure_details1
= sts_reg
,
73 .failure_details2
= src_id
,
76 ipmi_send_to_bmc((unsigned char *)&ubslp
, sizeof(ubslp
));
77 printk(BIOS_DEBUG
, "\tsending PCI device FAILURE record to BMC\n");
78 printk(BIOS_DEBUG
, "\terror_code = %x, src_id = %x\n", ubslp
.type
,
79 ubslp
.failure_details2
);
82 enum cb_err
ipmi_get_board_config(const int port
, struct ipmi_config_rsp
*config
)
87 struct ipmi_config_rsp data
;
90 struct ipmi_oem_rsp rsp
;
92 ret
= ipmi_message(port
, IPMI_NETFN_OEM
, 0x0, IPMI_OEM_GET_BOARD_ID
, NULL
, 0,
93 (unsigned char *)&rsp
, sizeof(rsp
));
94 if (ret
< sizeof(struct ipmi_rsp
) || rsp
.resp
.completion_code
) {
95 printk(BIOS_ERR
, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
96 __func__
, ret
, rsp
.resp
.completion_code
);
103 __weak
uint8_t get_blade_id(void)
105 struct ipmi_config_rsp rsp
= {.slot_id
= UINT8_MAX
};
107 if (CONFIG(IPMI_KCS
) && CONFIG_BMC_KCS_BASE
!= 0) {
108 if (ipmi_get_board_config(CONFIG_BMC_KCS_BASE
, &rsp
) != CB_SUCCESS
)