blob: 4ff900474175b19e131aaa07f93d3214910311c1 [file] [log] [blame]
Sergii Dmytrukef7dd5d2021-10-22 01:02:32 +03001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include "ipmi_if.h"
4
5#include <console/console.h>
6#include <delay.h>
7
8#include "chip.h"
9
10int ipmi_get_device_id(const struct device *dev, struct ipmi_devid_rsp *rsp)
11{
12 int ret;
13
14 ret = ipmi_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0,
15 IPMI_BMC_GET_DEVICE_ID, NULL, 0, (u8 *)rsp,
16 sizeof(*rsp));
17 if (ret < sizeof(struct ipmi_rsp) || rsp->resp.completion_code) {
18 printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
19 __func__, ret, rsp->resp.completion_code);
20 return 1;
21 }
22 if (ret != sizeof(*rsp)) {
23 printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__);
24 return 1;
25 }
26 return 0;
27}
28
29static int ipmi_get_bmc_self_test_result(const struct device *dev,
30 struct ipmi_selftest_rsp *rsp)
31{
32 int ret;
33
34 ret = ipmi_message(dev->path.pnp.port, IPMI_NETFN_APPLICATION, 0,
35 IPMI_BMC_GET_SELFTEST_RESULTS, NULL, 0, (u8 *)rsp,
36 sizeof(*rsp));
37
38 if (ret < sizeof(struct ipmi_rsp) || rsp->resp.completion_code) {
39 printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
40 __func__, ret, rsp->resp.completion_code);
41 return 1;
42 }
43 if (ret != sizeof(*rsp)) {
44 printk(BIOS_ERR, "IPMI: %s response truncated\n", __func__);
45 return 1;
46 }
47
48 return 0;
49}
50
51int ipmi_process_self_test_result(const struct device *dev)
52{
53 int failure = 0;
54 uint8_t retry_count = 0;
55 struct ipmi_selftest_rsp selftestrsp = {0};
56
57 const struct drivers_ipmi_config *conf = dev->chip_info;
58 uint8_t retry_limit = 0;
59
60 if (conf && conf->wait_for_bmc)
61 retry_limit = conf->bmc_boot_timeout;
62
63 if (retry_limit == 0)
64 /* Try to get self-test results at least once */
65 retry_limit = 1;
66
67 printk(BIOS_INFO, "Get BMC self test result...");
68 for (retry_count = 0; retry_count < retry_limit; retry_count++) {
69 if (!ipmi_get_bmc_self_test_result(dev, &selftestrsp))
70 break;
71
72 mdelay(1000);
73 }
74
75 switch (selftestrsp.result) {
76 case IPMI_APP_SELFTEST_NO_ERROR: /* 0x55 */
77 printk(BIOS_DEBUG, "No Error\n");
78 break;
79 case IPMI_APP_SELFTEST_NOT_IMPLEMENTED: /* 0x56 */
80 printk(BIOS_DEBUG, "Function Not Implemented\n");
81 break;
82 case IPMI_APP_SELFTEST_ERROR: /* 0x57 */
83 printk(BIOS_ERR, "BMC: Corrupted or inaccessible data or device\n");
84 failure = 1;
85 break;
86 case IPMI_APP_SELFTEST_FATAL_HW_ERROR: /* 0x58 */
87 printk(BIOS_ERR, "BMC: Fatal Hardware Error\n");
88 failure = 1;
89 break;
90 case IPMI_APP_SELFTEST_RESERVED: /* 0xFF */
91 printk(BIOS_DEBUG, "Reserved\n");
92 break;
93
94 default: /* Other Device Specific Hardware Error */
95 printk(BIOS_ERR, "BMC: Device Specific Error: 0x%02x\n", selftestrsp.result);
96 failure = 1;
97 break;
98 }
99
100 return failure;
101}