Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / huawei / hinic / hinic_devlink.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Huawei HiNIC PCI Express Linux driver
3  * Copyright(c) 2017 Huawei Technologies Co., Ltd
4  *
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.
8  *
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
12  * for more details.
13  *
14  */
15 #include <linux/netlink.h>
16 #include <net/devlink.h>
17 #include <linux/firmware.h>
18
19 #include "hinic_port.h"
20 #include "hinic_devlink.h"
21 #include "hinic_hw_dev.h"
22
23 static bool check_image_valid(struct hinic_devlink_priv *priv, const u8 *buf,
24                               u32 image_size, struct host_image_st *host_image)
25 {
26         struct fw_image_st *fw_image = NULL;
27         u32 len = 0;
28         u32 i;
29
30         fw_image = (struct fw_image_st *)buf;
31
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",
34                         fw_image->fw_magic);
35                 return false;
36         }
37
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);
41                 return false;
42         }
43
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));
49         }
50
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");
54                 return false;
55         }
56
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;
61
62         return true;
63 }
64
65 static bool check_image_integrity(struct hinic_devlink_priv *priv,
66                                   struct host_image_st *host_image,
67                                   u32 update_type)
68 {
69         u32 collect_section_type = 0;
70         u32 i, type;
71
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",
76                                 type);
77                         return false;
78                 }
79                 collect_section_type |= (1U << type);
80         }
81
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))
86                 return true;
87
88         if (update_type == FW_UPDATE_HOT &&
89             (collect_section_type & _IMAGE_HOT_SUB_MODULES_MUST_IN) ==
90             _IMAGE_HOT_SUB_MODULES_MUST_IN)
91                 return true;
92
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);
97         else
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);
100
101         return false;
102 }
103
104 static int check_image_device_type(struct hinic_devlink_priv *priv,
105                                    u32 image_device_type)
106 {
107         struct hinic_comm_board_info board_info = {0};
108
109         if (hinic_get_board_info(priv->hwdev, &board_info)) {
110                 dev_err(&priv->hwdev->hwif->pdev->dev, "Get board info failed\n");
111                 return false;
112         }
113
114         if (image_device_type == board_info.info.board_type)
115                 return true;
116
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);
120
121         return false;
122 }
123
124 static int hinic_flash_fw(struct hinic_devlink_priv *priv, const u8 *data,
125                           struct host_image_st *host_image)
126 {
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;
133         int err;
134
135         fw_update_msg = kzalloc(sizeof(*fw_update_msg), GFP_KERNEL);
136         if (!fw_update_msg)
137                 return -ENOMEM;
138
139         up_total_len = host_image->image_info.up_total_len;
140
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 ==
144                     UP_FW_UPDATE_BOOT) {
145                         up_total_len = up_total_len - len;
146                         break;
147                 }
148         }
149
150         for (i = 0; i < host_image->section_type_num; i++) {
151                 section_len =
152                         host_image->image_section_info[i].fw_section_len;
153                 section_offset =
154                         host_image->image_section_info[i].fw_section_offset;
155                 section_remain_send_len = section_len;
156                 section_type =
157                         host_image->image_section_info[i].fw_section_type;
158                 section_crc = host_image->image_section_info[i].fw_section_crc;
159                 section_version =
160                         host_image->image_section_info[i].fw_section_version;
161
162                 if (section_type == UP_FW_UPDATE_BOOT)
163                         continue;
164
165                 send_fragment_len = 0;
166                 send_pos = 0;
167
168                 while (section_remain_send_len > 0) {
169                         if (!total_len_flag) {
170                                 fw_update_msg->total_len = up_total_len;
171                                 total_len_flag = 1;
172                         } else {
173                                 fw_update_msg->total_len = 0;
174                         }
175
176                         memset(fw_update_msg->data, 0, MAX_FW_FRAGMENT_LEN);
177
178                         fw_update_msg->ctl_info.SF =
179                                 (section_remain_send_len == section_len) ?
180                                 true : false;
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;
184
185                         if (section_type <= UP_FW_UPDATE_UP_DATA_B) {
186                                 fw_update_msg->section_info.FW_section_type =
187                                         (section_type % 2) ?
188                                         UP_FW_UPDATE_UP_DATA :
189                                         UP_FW_UPDATE_UP_TEXT;
190
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;
194                         } else {
195                                 fw_update_msg->section_info.FW_section_type =
196                                         section_type - 0x2;
197                         }
198
199                         fw_update_msg->setion_total_len = section_len;
200                         fw_update_msg->section_offset = send_pos;
201
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;
207                         } else {
208                                 fw_update_msg->ctl_info.SL = false;
209                                 fw_update_msg->ctl_info.fragment_len =
210                                         MAX_FW_FRAGMENT_LEN;
211                                 send_fragment_len += MAX_FW_FRAGMENT_LEN;
212                         }
213
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);
218
219                         err = hinic_port_msg_cmd(priv->hwdev,
220                                                  HINIC_PORT_CMD_UPDATE_FW,
221                                                  fw_update_msg,
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);
230                                 return err;
231                         }
232
233                         send_pos = send_fragment_len;
234                         section_remain_send_len = section_len -
235                                                   send_fragment_len;
236                 }
237         }
238
239         kfree(fw_update_msg);
240
241         return 0;
242 }
243
244 static int hinic_firmware_update(struct hinic_devlink_priv *priv,
245                                  const struct firmware *fw,
246                                  struct netlink_ext_ack *extack)
247 {
248         struct host_image_st host_image;
249         int err;
250
251         memset(&host_image, 0, sizeof(struct host_image_st));
252
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");
257                 return -EINVAL;
258         }
259
260         dev_info(&priv->hwdev->hwif->pdev->dev, "Flash firmware begin\n");
261
262         err = hinic_flash_fw(priv, fw->data, &host_image);
263         if (err) {
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",
266                                 err);
267                         NL_SET_ERR_MSG_MOD(extack,
268                                            "Firmware image doesn't match this card, please use newer image");
269                 } else {
270                         dev_err(&priv->hwdev->hwif->pdev->dev, "Send firmware image data failed, err: %d\n",
271                                 err);
272                         NL_SET_ERR_MSG_MOD(extack, "Send firmware image data failed");
273                 }
274
275                 return err;
276         }
277
278         dev_info(&priv->hwdev->hwif->pdev->dev, "Flash firmware end\n");
279
280         return 0;
281 }
282
283 static int hinic_devlink_flash_update(struct devlink *devlink,
284                                       const char *file_name,
285                                       const char *component,
286                                       struct netlink_ext_ack *extack)
287 {
288         struct hinic_devlink_priv *priv = devlink_priv(devlink);
289         const struct firmware *fw;
290         int err;
291
292         if (component)
293                 return -EOPNOTSUPP;
294
295         err = request_firmware_direct(&fw, file_name,
296                                       &priv->hwdev->hwif->pdev->dev);
297         if (err)
298                 return err;
299
300         err = hinic_firmware_update(priv, fw, extack);
301         release_firmware(fw);
302
303         return err;
304 }
305
306 static const struct devlink_ops hinic_devlink_ops = {
307         .flash_update = hinic_devlink_flash_update,
308 };
309
310 struct devlink *hinic_devlink_alloc(void)
311 {
312         return devlink_alloc(&hinic_devlink_ops, sizeof(struct hinic_dev));
313 }
314
315 void hinic_devlink_free(struct devlink *devlink)
316 {
317         devlink_free(devlink);
318 }
319
320 int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev)
321 {
322         struct devlink *devlink = priv_to_devlink(priv);
323
324         return devlink_register(devlink, dev);
325 }
326
327 void hinic_devlink_unregister(struct hinic_devlink_priv *priv)
328 {
329         struct devlink *devlink = priv_to_devlink(priv);
330
331         devlink_unregister(devlink);
332 }
333
334 static int chip_fault_show(struct devlink_fmsg *fmsg,
335                            struct hinic_fault_event *event)
336 {
337         const char * const level_str[FAULT_LEVEL_MAX + 1] = {
338                 "fatal", "reset", "flr", "general", "suggestion", "Unknown"};
339         u8 fault_level;
340         int err;
341
342         fault_level = (event->event.chip.err_level < FAULT_LEVEL_MAX) ?
343                 event->event.chip.err_level : FAULT_LEVEL_MAX;
344         if (fault_level == FAULT_LEVEL_SERIOUS_FLR) {
345                 err = devlink_fmsg_u32_pair_put(fmsg, "Function level err func_id",
346                                                 (u32)event->event.chip.func_id);
347                 if (err)
348                         return err;
349         }
350
351         err = devlink_fmsg_u8_pair_put(fmsg, "module_id", event->event.chip.node_id);
352         if (err)
353                 return err;
354
355         err = devlink_fmsg_u32_pair_put(fmsg, "err_type", (u32)event->event.chip.err_type);
356         if (err)
357                 return err;
358
359         err = devlink_fmsg_string_pair_put(fmsg, "err_level", level_str[fault_level]);
360         if (err)
361                 return err;
362
363         err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_addr",
364                                         event->event.chip.err_csr_addr);
365         if (err)
366                 return err;
367
368         err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_value",
369                                         event->event.chip.err_csr_value);
370         if (err)
371                 return err;
372
373         return 0;
374 }
375
376 static int fault_report_show(struct devlink_fmsg *fmsg,
377                              struct hinic_fault_event *event)
378 {
379         const char * const type_str[FAULT_TYPE_MAX + 1] = {
380                 "chip", "ucode", "mem rd timeout", "mem wr timeout",
381                 "reg rd timeout", "reg wr timeout", "phy fault", "Unknown"};
382         u8 fault_type;
383         int err;
384
385         fault_type = (event->type < FAULT_TYPE_MAX) ? event->type : FAULT_TYPE_MAX;
386
387         err = devlink_fmsg_string_pair_put(fmsg, "Fault type", type_str[fault_type]);
388         if (err)
389                 return err;
390
391         err = devlink_fmsg_binary_pair_put(fmsg, "Fault raw data",
392                                            event->event.val, sizeof(event->event.val));
393         if (err)
394                 return err;
395
396         switch (event->type) {
397         case FAULT_TYPE_CHIP:
398                 err = chip_fault_show(fmsg, event);
399                 if (err)
400                         return err;
401                 break;
402         case FAULT_TYPE_UCODE:
403                 err = devlink_fmsg_u8_pair_put(fmsg, "Cause_id", event->event.ucode.cause_id);
404                 if (err)
405                         return err;
406                 err = devlink_fmsg_u8_pair_put(fmsg, "core_id", event->event.ucode.core_id);
407                 if (err)
408                         return err;
409                 err = devlink_fmsg_u8_pair_put(fmsg, "c_id", event->event.ucode.c_id);
410                 if (err)
411                         return err;
412                 err = devlink_fmsg_u8_pair_put(fmsg, "epc", event->event.ucode.epc);
413                 if (err)
414                         return err;
415                 break;
416         case FAULT_TYPE_MEM_RD_TIMEOUT:
417         case FAULT_TYPE_MEM_WR_TIMEOUT:
418                 err = devlink_fmsg_u32_pair_put(fmsg, "Err_csr_ctrl",
419                                                 event->event.mem_timeout.err_csr_ctrl);
420                 if (err)
421                         return err;
422                 err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_data",
423                                                 event->event.mem_timeout.err_csr_data);
424                 if (err)
425                         return err;
426                 err = devlink_fmsg_u32_pair_put(fmsg, "ctrl_tab",
427                                                 event->event.mem_timeout.ctrl_tab);
428                 if (err)
429                         return err;
430                 err = devlink_fmsg_u32_pair_put(fmsg, "mem_index",
431                                                 event->event.mem_timeout.mem_index);
432                 if (err)
433                         return err;
434                 break;
435         case FAULT_TYPE_REG_RD_TIMEOUT:
436         case FAULT_TYPE_REG_WR_TIMEOUT:
437                 err = devlink_fmsg_u32_pair_put(fmsg, "Err_csr", event->event.reg_timeout.err_csr);
438                 if (err)
439                         return err;
440                 break;
441         case FAULT_TYPE_PHY_FAULT:
442                 err = devlink_fmsg_u8_pair_put(fmsg, "Op_type", event->event.phy_fault.op_type);
443                 if (err)
444                         return err;
445                 err = devlink_fmsg_u8_pair_put(fmsg, "port_id", event->event.phy_fault.port_id);
446                 if (err)
447                         return err;
448                 err = devlink_fmsg_u8_pair_put(fmsg, "dev_ad", event->event.phy_fault.dev_ad);
449                 if (err)
450                         return err;
451
452                 err = devlink_fmsg_u32_pair_put(fmsg, "csr_addr", event->event.phy_fault.csr_addr);
453                 if (err)
454                         return err;
455                 err = devlink_fmsg_u32_pair_put(fmsg, "op_data", event->event.phy_fault.op_data);
456                 if (err)
457                         return err;
458                 break;
459         default:
460                 break;
461         }
462
463         return 0;
464 }
465
466 static int hinic_hw_reporter_dump(struct devlink_health_reporter *reporter,
467                                   struct devlink_fmsg *fmsg, void *priv_ctx,
468                                   struct netlink_ext_ack *extack)
469 {
470         if (priv_ctx)
471                 return fault_report_show(fmsg, priv_ctx);
472
473         return 0;
474 }
475
476 static int mgmt_watchdog_report_show(struct devlink_fmsg *fmsg,
477                                      struct hinic_mgmt_watchdog_info *watchdog_info)
478 {
479         int err;
480
481         err = devlink_fmsg_u32_pair_put(fmsg, "Mgmt deadloop time_h", watchdog_info->curr_time_h);
482         if (err)
483                 return err;
484
485         err = devlink_fmsg_u32_pair_put(fmsg, "time_l", watchdog_info->curr_time_l);
486         if (err)
487                 return err;
488
489         err = devlink_fmsg_u32_pair_put(fmsg, "task_id", watchdog_info->task_id);
490         if (err)
491                 return err;
492
493         err = devlink_fmsg_u32_pair_put(fmsg, "sp", watchdog_info->sp);
494         if (err)
495                 return err;
496
497         err = devlink_fmsg_u32_pair_put(fmsg, "stack_current_used", watchdog_info->curr_used);
498         if (err)
499                 return err;
500
501         err = devlink_fmsg_u32_pair_put(fmsg, "peak_used", watchdog_info->peak_used);
502         if (err)
503                 return err;
504
505         err = devlink_fmsg_u32_pair_put(fmsg, "\n Overflow_flag", watchdog_info->is_overflow);
506         if (err)
507                 return err;
508
509         err = devlink_fmsg_u32_pair_put(fmsg, "stack_top", watchdog_info->stack_top);
510         if (err)
511                 return err;
512
513         err = devlink_fmsg_u32_pair_put(fmsg, "stack_bottom", watchdog_info->stack_bottom);
514         if (err)
515                 return err;
516
517         err = devlink_fmsg_u32_pair_put(fmsg, "mgmt_pc", watchdog_info->pc);
518         if (err)
519                 return err;
520
521         err = devlink_fmsg_u32_pair_put(fmsg, "lr", watchdog_info->lr);
522         if (err)
523                 return err;
524
525         err = devlink_fmsg_u32_pair_put(fmsg, "cpsr", watchdog_info->cpsr);
526         if (err)
527                 return err;
528
529         err = devlink_fmsg_binary_pair_put(fmsg, "Mgmt register info",
530                                            watchdog_info->reg, sizeof(watchdog_info->reg));
531         if (err)
532                 return err;
533
534         err = devlink_fmsg_binary_pair_put(fmsg, "Mgmt dump stack(start from sp)",
535                                            watchdog_info->data, sizeof(watchdog_info->data));
536         if (err)
537                 return err;
538
539         return 0;
540 }
541
542 static int hinic_fw_reporter_dump(struct devlink_health_reporter *reporter,
543                                   struct devlink_fmsg *fmsg, void *priv_ctx,
544                                   struct netlink_ext_ack *extack)
545 {
546         if (priv_ctx)
547                 return mgmt_watchdog_report_show(fmsg, priv_ctx);
548
549         return 0;
550 }
551
552 static const struct devlink_health_reporter_ops hinic_hw_fault_reporter_ops = {
553         .name = "hw",
554         .dump = hinic_hw_reporter_dump,
555 };
556
557 static const struct devlink_health_reporter_ops hinic_fw_fault_reporter_ops = {
558         .name = "fw",
559         .dump = hinic_fw_reporter_dump,
560 };
561
562 int hinic_health_reporters_create(struct hinic_devlink_priv *priv)
563 {
564         struct devlink *devlink = priv_to_devlink(priv);
565
566         priv->hw_fault_reporter =
567                 devlink_health_reporter_create(devlink, &hinic_hw_fault_reporter_ops,
568                                                0, priv);
569         if (IS_ERR(priv->hw_fault_reporter)) {
570                 dev_warn(&priv->hwdev->hwif->pdev->dev, "Failed to create hw fault reporter, err: %ld\n",
571                          PTR_ERR(priv->hw_fault_reporter));
572                 return PTR_ERR(priv->hw_fault_reporter);
573         }
574
575         priv->fw_fault_reporter =
576                 devlink_health_reporter_create(devlink, &hinic_fw_fault_reporter_ops,
577                                                0, priv);
578         if (IS_ERR(priv->fw_fault_reporter)) {
579                 dev_warn(&priv->hwdev->hwif->pdev->dev, "Failed to create fw fault reporter, err: %ld\n",
580                          PTR_ERR(priv->fw_fault_reporter));
581                 devlink_health_reporter_destroy(priv->hw_fault_reporter);
582                 priv->hw_fault_reporter = NULL;
583                 return PTR_ERR(priv->fw_fault_reporter);
584         }
585
586         return 0;
587 }
588
589 void hinic_health_reporters_destroy(struct hinic_devlink_priv *priv)
590 {
591         if (!IS_ERR_OR_NULL(priv->fw_fault_reporter)) {
592                 devlink_health_reporter_destroy(priv->fw_fault_reporter);
593                 priv->fw_fault_reporter = NULL;
594         }
595
596         if (!IS_ERR_OR_NULL(priv->hw_fault_reporter)) {
597                 devlink_health_reporter_destroy(priv->hw_fault_reporter);
598                 priv->hw_fault_reporter = NULL;
599         }
600 }