1 // SPDX-License-Identifier: GPL-2.0
2 /* Huawei HiNIC PCI Express Linux driver
3 * Copyright(c) 2017 Huawei Technologies Co., Ltd
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 #include <linux/netlink.h>
16 #include <net/devlink.h>
17 #include <linux/firmware.h>
19 #include "hinic_port.h"
20 #include "hinic_devlink.h"
21 #include "hinic_hw_dev.h"
23 static bool check_image_valid(struct hinic_devlink_priv
*priv
, const u8
*buf
,
24 u32 image_size
, struct host_image_st
*host_image
)
26 struct fw_image_st
*fw_image
= NULL
;
30 fw_image
= (struct fw_image_st
*)buf
;
32 if (fw_image
->fw_magic
!= HINIC_MAGIC_NUM
) {
33 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Wrong fw_magic read from file, fw_magic: 0x%x\n",
38 if (fw_image
->fw_info
.fw_section_cnt
> MAX_FW_TYPE_NUM
) {
39 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Wrong fw_type_num read from file, fw_type_num: 0x%x\n",
40 fw_image
->fw_info
.fw_section_cnt
);
44 for (i
= 0; i
< fw_image
->fw_info
.fw_section_cnt
; i
++) {
45 len
+= fw_image
->fw_section_info
[i
].fw_section_len
;
46 memcpy(&host_image
->image_section_info
[i
],
47 &fw_image
->fw_section_info
[i
],
48 sizeof(struct fw_section_info_st
));
51 if (len
!= fw_image
->fw_len
||
52 (fw_image
->fw_len
+ UPDATEFW_IMAGE_HEAD_SIZE
) != image_size
) {
53 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Wrong data size read from file\n");
57 host_image
->image_info
.up_total_len
= fw_image
->fw_len
;
58 host_image
->image_info
.fw_version
= fw_image
->fw_version
;
59 host_image
->section_type_num
= fw_image
->fw_info
.fw_section_cnt
;
60 host_image
->device_id
= fw_image
->device_id
;
65 static bool check_image_integrity(struct hinic_devlink_priv
*priv
,
66 struct host_image_st
*host_image
,
69 u32 collect_section_type
= 0;
72 for (i
= 0; i
< host_image
->section_type_num
; i
++) {
73 type
= host_image
->image_section_info
[i
].fw_section_type
;
74 if (collect_section_type
& (1U << type
)) {
75 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Duplicate section type: %u\n",
79 collect_section_type
|= (1U << type
);
82 if (update_type
== FW_UPDATE_COLD
&&
83 (((collect_section_type
& _IMAGE_COLD_SUB_MODULES_MUST_IN
) ==
84 _IMAGE_COLD_SUB_MODULES_MUST_IN
) ||
85 collect_section_type
== _IMAGE_CFG_SUB_MODULES_MUST_IN
))
88 if (update_type
== FW_UPDATE_HOT
&&
89 (collect_section_type
& _IMAGE_HOT_SUB_MODULES_MUST_IN
) ==
90 _IMAGE_HOT_SUB_MODULES_MUST_IN
)
93 if (update_type
== FW_UPDATE_COLD
)
94 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Check file integrity failed, valid: 0x%x or 0x%lx, current: 0x%x\n",
95 _IMAGE_COLD_SUB_MODULES_MUST_IN
,
96 _IMAGE_CFG_SUB_MODULES_MUST_IN
, collect_section_type
);
98 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Check file integrity failed, valid:0x%x, current: 0x%x\n",
99 _IMAGE_HOT_SUB_MODULES_MUST_IN
, collect_section_type
);
104 static int check_image_device_type(struct hinic_devlink_priv
*priv
,
105 u32 image_device_type
)
107 struct hinic_comm_board_info board_info
= {0};
109 if (hinic_get_board_info(priv
->hwdev
, &board_info
)) {
110 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Get board info failed\n");
114 if (image_device_type
== board_info
.info
.board_type
)
117 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "The device type of upgrade file doesn't match the device type of current firmware, please check the upgrade file\n");
118 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "The image device type: 0x%x, firmware device type: 0x%x\n",
119 image_device_type
, board_info
.info
.board_type
);
124 static int hinic_flash_fw(struct hinic_devlink_priv
*priv
, const u8
*data
,
125 struct host_image_st
*host_image
)
127 u32 section_remain_send_len
, send_fragment_len
, send_pos
, up_total_len
;
128 struct hinic_cmd_update_fw
*fw_update_msg
= NULL
;
129 u32 section_type
, section_crc
, section_version
;
130 u32 i
, len
, section_len
, section_offset
;
131 u16 out_size
= sizeof(*fw_update_msg
);
132 int total_len_flag
= 0;
135 fw_update_msg
= kzalloc(sizeof(*fw_update_msg
), GFP_KERNEL
);
139 up_total_len
= host_image
->image_info
.up_total_len
;
141 for (i
= 0; i
< host_image
->section_type_num
; i
++) {
142 len
= host_image
->image_section_info
[i
].fw_section_len
;
143 if (host_image
->image_section_info
[i
].fw_section_type
==
145 up_total_len
= up_total_len
- len
;
150 for (i
= 0; i
< host_image
->section_type_num
; i
++) {
152 host_image
->image_section_info
[i
].fw_section_len
;
154 host_image
->image_section_info
[i
].fw_section_offset
;
155 section_remain_send_len
= section_len
;
157 host_image
->image_section_info
[i
].fw_section_type
;
158 section_crc
= host_image
->image_section_info
[i
].fw_section_crc
;
160 host_image
->image_section_info
[i
].fw_section_version
;
162 if (section_type
== UP_FW_UPDATE_BOOT
)
165 send_fragment_len
= 0;
168 while (section_remain_send_len
> 0) {
169 if (!total_len_flag
) {
170 fw_update_msg
->total_len
= up_total_len
;
173 fw_update_msg
->total_len
= 0;
176 memset(fw_update_msg
->data
, 0, MAX_FW_FRAGMENT_LEN
);
178 fw_update_msg
->ctl_info
.SF
=
179 (section_remain_send_len
== section_len
) ?
181 fw_update_msg
->section_info
.FW_section_CRC
= section_crc
;
182 fw_update_msg
->fw_section_version
= section_version
;
183 fw_update_msg
->ctl_info
.flag
= UP_TYPE_A
;
185 if (section_type
<= UP_FW_UPDATE_UP_DATA_B
) {
186 fw_update_msg
->section_info
.FW_section_type
=
188 UP_FW_UPDATE_UP_DATA
:
189 UP_FW_UPDATE_UP_TEXT
;
191 fw_update_msg
->ctl_info
.flag
= UP_TYPE_B
;
192 if (section_type
<= UP_FW_UPDATE_UP_DATA_A
)
193 fw_update_msg
->ctl_info
.flag
= UP_TYPE_A
;
195 fw_update_msg
->section_info
.FW_section_type
=
199 fw_update_msg
->setion_total_len
= section_len
;
200 fw_update_msg
->section_offset
= send_pos
;
202 if (section_remain_send_len
<= MAX_FW_FRAGMENT_LEN
) {
203 fw_update_msg
->ctl_info
.SL
= true;
204 fw_update_msg
->ctl_info
.fragment_len
=
205 section_remain_send_len
;
206 send_fragment_len
+= section_remain_send_len
;
208 fw_update_msg
->ctl_info
.SL
= false;
209 fw_update_msg
->ctl_info
.fragment_len
=
211 send_fragment_len
+= MAX_FW_FRAGMENT_LEN
;
214 memcpy(fw_update_msg
->data
,
215 data
+ UPDATEFW_IMAGE_HEAD_SIZE
+
216 section_offset
+ send_pos
,
217 fw_update_msg
->ctl_info
.fragment_len
);
219 err
= hinic_port_msg_cmd(priv
->hwdev
,
220 HINIC_PORT_CMD_UPDATE_FW
,
222 sizeof(*fw_update_msg
),
223 fw_update_msg
, &out_size
);
224 if (err
|| !out_size
|| fw_update_msg
->status
) {
225 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Failed to update firmware, err: %d, status: 0x%x, out size: 0x%x\n",
226 err
, fw_update_msg
->status
, out_size
);
227 err
= fw_update_msg
->status
?
228 fw_update_msg
->status
: -EIO
;
229 kfree(fw_update_msg
);
233 send_pos
= send_fragment_len
;
234 section_remain_send_len
= section_len
-
239 kfree(fw_update_msg
);
244 static int hinic_firmware_update(struct hinic_devlink_priv
*priv
,
245 const struct firmware
*fw
,
246 struct netlink_ext_ack
*extack
)
248 struct host_image_st host_image
;
251 memset(&host_image
, 0, sizeof(struct host_image_st
));
253 if (!check_image_valid(priv
, fw
->data
, fw
->size
, &host_image
) ||
254 !check_image_integrity(priv
, &host_image
, FW_UPDATE_COLD
) ||
255 !check_image_device_type(priv
, host_image
.device_id
)) {
256 NL_SET_ERR_MSG_MOD(extack
, "Check image failed");
260 dev_info(&priv
->hwdev
->hwif
->pdev
->dev
, "Flash firmware begin\n");
262 err
= hinic_flash_fw(priv
, fw
->data
, &host_image
);
264 if (err
== HINIC_FW_DISMATCH_ERROR
) {
265 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Firmware image doesn't match this card, please use newer image, err: %d\n",
267 NL_SET_ERR_MSG_MOD(extack
,
268 "Firmware image doesn't match this card, please use newer image");
270 dev_err(&priv
->hwdev
->hwif
->pdev
->dev
, "Send firmware image data failed, err: %d\n",
272 NL_SET_ERR_MSG_MOD(extack
, "Send firmware image data failed");
278 dev_info(&priv
->hwdev
->hwif
->pdev
->dev
, "Flash firmware end\n");
283 static int hinic_devlink_flash_update(struct devlink
*devlink
,
284 struct devlink_flash_update_params
*params
,
285 struct netlink_ext_ack
*extack
)
287 struct hinic_devlink_priv
*priv
= devlink_priv(devlink
);
289 return hinic_firmware_update(priv
, params
->fw
, extack
);
292 static const struct devlink_ops hinic_devlink_ops
= {
293 .flash_update
= hinic_devlink_flash_update
,
296 struct devlink
*hinic_devlink_alloc(void)
298 return devlink_alloc(&hinic_devlink_ops
, sizeof(struct hinic_dev
));
301 void hinic_devlink_free(struct devlink
*devlink
)
303 devlink_free(devlink
);
306 int hinic_devlink_register(struct hinic_devlink_priv
*priv
, struct device
*dev
)
308 struct devlink
*devlink
= priv_to_devlink(priv
);
310 return devlink_register(devlink
, dev
);
313 void hinic_devlink_unregister(struct hinic_devlink_priv
*priv
)
315 struct devlink
*devlink
= priv_to_devlink(priv
);
317 devlink_unregister(devlink
);
320 static int chip_fault_show(struct devlink_fmsg
*fmsg
,
321 struct hinic_fault_event
*event
)
323 const char * const level_str
[FAULT_LEVEL_MAX
+ 1] = {
324 "fatal", "reset", "flr", "general", "suggestion", "Unknown"};
328 fault_level
= (event
->event
.chip
.err_level
< FAULT_LEVEL_MAX
) ?
329 event
->event
.chip
.err_level
: FAULT_LEVEL_MAX
;
330 if (fault_level
== FAULT_LEVEL_SERIOUS_FLR
) {
331 err
= devlink_fmsg_u32_pair_put(fmsg
, "Function level err func_id",
332 (u32
)event
->event
.chip
.func_id
);
337 err
= devlink_fmsg_u8_pair_put(fmsg
, "module_id", event
->event
.chip
.node_id
);
341 err
= devlink_fmsg_u32_pair_put(fmsg
, "err_type", (u32
)event
->event
.chip
.err_type
);
345 err
= devlink_fmsg_string_pair_put(fmsg
, "err_level", level_str
[fault_level
]);
349 err
= devlink_fmsg_u32_pair_put(fmsg
, "err_csr_addr",
350 event
->event
.chip
.err_csr_addr
);
354 err
= devlink_fmsg_u32_pair_put(fmsg
, "err_csr_value",
355 event
->event
.chip
.err_csr_value
);
362 static int fault_report_show(struct devlink_fmsg
*fmsg
,
363 struct hinic_fault_event
*event
)
365 const char * const type_str
[FAULT_TYPE_MAX
+ 1] = {
366 "chip", "ucode", "mem rd timeout", "mem wr timeout",
367 "reg rd timeout", "reg wr timeout", "phy fault", "Unknown"};
371 fault_type
= (event
->type
< FAULT_TYPE_MAX
) ? event
->type
: FAULT_TYPE_MAX
;
373 err
= devlink_fmsg_string_pair_put(fmsg
, "Fault type", type_str
[fault_type
]);
377 err
= devlink_fmsg_binary_pair_put(fmsg
, "Fault raw data",
378 event
->event
.val
, sizeof(event
->event
.val
));
382 switch (event
->type
) {
383 case FAULT_TYPE_CHIP
:
384 err
= chip_fault_show(fmsg
, event
);
388 case FAULT_TYPE_UCODE
:
389 err
= devlink_fmsg_u8_pair_put(fmsg
, "Cause_id", event
->event
.ucode
.cause_id
);
392 err
= devlink_fmsg_u8_pair_put(fmsg
, "core_id", event
->event
.ucode
.core_id
);
395 err
= devlink_fmsg_u8_pair_put(fmsg
, "c_id", event
->event
.ucode
.c_id
);
398 err
= devlink_fmsg_u8_pair_put(fmsg
, "epc", event
->event
.ucode
.epc
);
402 case FAULT_TYPE_MEM_RD_TIMEOUT
:
403 case FAULT_TYPE_MEM_WR_TIMEOUT
:
404 err
= devlink_fmsg_u32_pair_put(fmsg
, "Err_csr_ctrl",
405 event
->event
.mem_timeout
.err_csr_ctrl
);
408 err
= devlink_fmsg_u32_pair_put(fmsg
, "err_csr_data",
409 event
->event
.mem_timeout
.err_csr_data
);
412 err
= devlink_fmsg_u32_pair_put(fmsg
, "ctrl_tab",
413 event
->event
.mem_timeout
.ctrl_tab
);
416 err
= devlink_fmsg_u32_pair_put(fmsg
, "mem_index",
417 event
->event
.mem_timeout
.mem_index
);
421 case FAULT_TYPE_REG_RD_TIMEOUT
:
422 case FAULT_TYPE_REG_WR_TIMEOUT
:
423 err
= devlink_fmsg_u32_pair_put(fmsg
, "Err_csr", event
->event
.reg_timeout
.err_csr
);
427 case FAULT_TYPE_PHY_FAULT
:
428 err
= devlink_fmsg_u8_pair_put(fmsg
, "Op_type", event
->event
.phy_fault
.op_type
);
431 err
= devlink_fmsg_u8_pair_put(fmsg
, "port_id", event
->event
.phy_fault
.port_id
);
434 err
= devlink_fmsg_u8_pair_put(fmsg
, "dev_ad", event
->event
.phy_fault
.dev_ad
);
438 err
= devlink_fmsg_u32_pair_put(fmsg
, "csr_addr", event
->event
.phy_fault
.csr_addr
);
441 err
= devlink_fmsg_u32_pair_put(fmsg
, "op_data", event
->event
.phy_fault
.op_data
);
452 static int hinic_hw_reporter_dump(struct devlink_health_reporter
*reporter
,
453 struct devlink_fmsg
*fmsg
, void *priv_ctx
,
454 struct netlink_ext_ack
*extack
)
457 return fault_report_show(fmsg
, priv_ctx
);
462 static int mgmt_watchdog_report_show(struct devlink_fmsg
*fmsg
,
463 struct hinic_mgmt_watchdog_info
*watchdog_info
)
467 err
= devlink_fmsg_u32_pair_put(fmsg
, "Mgmt deadloop time_h", watchdog_info
->curr_time_h
);
471 err
= devlink_fmsg_u32_pair_put(fmsg
, "time_l", watchdog_info
->curr_time_l
);
475 err
= devlink_fmsg_u32_pair_put(fmsg
, "task_id", watchdog_info
->task_id
);
479 err
= devlink_fmsg_u32_pair_put(fmsg
, "sp", watchdog_info
->sp
);
483 err
= devlink_fmsg_u32_pair_put(fmsg
, "stack_current_used", watchdog_info
->curr_used
);
487 err
= devlink_fmsg_u32_pair_put(fmsg
, "peak_used", watchdog_info
->peak_used
);
491 err
= devlink_fmsg_u32_pair_put(fmsg
, "\n Overflow_flag", watchdog_info
->is_overflow
);
495 err
= devlink_fmsg_u32_pair_put(fmsg
, "stack_top", watchdog_info
->stack_top
);
499 err
= devlink_fmsg_u32_pair_put(fmsg
, "stack_bottom", watchdog_info
->stack_bottom
);
503 err
= devlink_fmsg_u32_pair_put(fmsg
, "mgmt_pc", watchdog_info
->pc
);
507 err
= devlink_fmsg_u32_pair_put(fmsg
, "lr", watchdog_info
->lr
);
511 err
= devlink_fmsg_u32_pair_put(fmsg
, "cpsr", watchdog_info
->cpsr
);
515 err
= devlink_fmsg_binary_pair_put(fmsg
, "Mgmt register info",
516 watchdog_info
->reg
, sizeof(watchdog_info
->reg
));
520 err
= devlink_fmsg_binary_pair_put(fmsg
, "Mgmt dump stack(start from sp)",
521 watchdog_info
->data
, sizeof(watchdog_info
->data
));
528 static int hinic_fw_reporter_dump(struct devlink_health_reporter
*reporter
,
529 struct devlink_fmsg
*fmsg
, void *priv_ctx
,
530 struct netlink_ext_ack
*extack
)
533 return mgmt_watchdog_report_show(fmsg
, priv_ctx
);
538 static const struct devlink_health_reporter_ops hinic_hw_fault_reporter_ops
= {
540 .dump
= hinic_hw_reporter_dump
,
543 static const struct devlink_health_reporter_ops hinic_fw_fault_reporter_ops
= {
545 .dump
= hinic_fw_reporter_dump
,
548 int hinic_health_reporters_create(struct hinic_devlink_priv
*priv
)
550 struct devlink
*devlink
= priv_to_devlink(priv
);
552 priv
->hw_fault_reporter
=
553 devlink_health_reporter_create(devlink
, &hinic_hw_fault_reporter_ops
,
555 if (IS_ERR(priv
->hw_fault_reporter
)) {
556 dev_warn(&priv
->hwdev
->hwif
->pdev
->dev
, "Failed to create hw fault reporter, err: %ld\n",
557 PTR_ERR(priv
->hw_fault_reporter
));
558 return PTR_ERR(priv
->hw_fault_reporter
);
561 priv
->fw_fault_reporter
=
562 devlink_health_reporter_create(devlink
, &hinic_fw_fault_reporter_ops
,
564 if (IS_ERR(priv
->fw_fault_reporter
)) {
565 dev_warn(&priv
->hwdev
->hwif
->pdev
->dev
, "Failed to create fw fault reporter, err: %ld\n",
566 PTR_ERR(priv
->fw_fault_reporter
));
567 devlink_health_reporter_destroy(priv
->hw_fault_reporter
);
568 priv
->hw_fault_reporter
= NULL
;
569 return PTR_ERR(priv
->fw_fault_reporter
);
575 void hinic_health_reporters_destroy(struct hinic_devlink_priv
*priv
)
577 if (!IS_ERR_OR_NULL(priv
->fw_fault_reporter
)) {
578 devlink_health_reporter_destroy(priv
->fw_fault_reporter
);
579 priv
->fw_fault_reporter
= NULL
;
582 if (!IS_ERR_OR_NULL(priv
->hw_fault_reporter
)) {
583 devlink_health_reporter_destroy(priv
->hw_fault_reporter
);
584 priv
->hw_fault_reporter
= NULL
;