Skip to content

Commit 1255457

Browse files
committed
Merge branch 'hinic-add-some-error-messages-for-debug'
Luo bin says: ==================== hinic: add some error messages for debug patch #1: support to handle hw abnormal event patch #2: improve the error messages when functions return failure and dump relevant registers in some exception handling processes ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents aff7543 + 90f86b8 commit 1255457

21 files changed

+855
-81
lines changed

drivers/net/ethernet/huawei/hinic/hinic_dev.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,14 @@ struct hinic_dev {
9898
int lb_pkt_len;
9999
u8 *lb_test_rx_buf;
100100
struct devlink *devlink;
101+
bool cable_unplugged;
102+
bool module_unrecognized;
101103
};
102104

103105
struct hinic_devlink_priv {
104106
struct hinic_hwdev *hwdev;
107+
struct devlink_health_reporter *hw_fault_reporter;
108+
struct devlink_health_reporter *fw_fault_reporter;
105109
};
106110

107111
#endif

drivers/net/ethernet/huawei/hinic/hinic_devlink.c

Lines changed: 283 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
#include <net/devlink.h>
1717
#include <linux/firmware.h>
1818

19-
#include "hinic_dev.h"
2019
#include "hinic_port.h"
2120
#include "hinic_devlink.h"
21+
#include "hinic_hw_dev.h"
2222

2323
static bool check_image_valid(struct hinic_devlink_priv *priv, const u8 *buf,
2424
u32 image_size, struct host_image_st *host_image)
@@ -317,12 +317,292 @@ void hinic_devlink_free(struct devlink *devlink)
317317
devlink_free(devlink);
318318
}
319319

320-
int hinic_devlink_register(struct devlink *devlink, struct device *dev)
320+
int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev)
321321
{
322+
struct devlink *devlink = priv_to_devlink(priv);
323+
322324
return devlink_register(devlink, dev);
323325
}
324326

325-
void hinic_devlink_unregister(struct devlink *devlink)
327+
void hinic_devlink_unregister(struct hinic_devlink_priv *priv)
326328
{
329+
struct devlink *devlink = priv_to_devlink(priv);
330+
327331
devlink_unregister(devlink);
328332
}
333+
334+
static int chip_fault_show(struct devlink_fmsg *fmsg,
335+
struct hinic_fault_event *event)
336+
{
337+
char fault_level[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
338+
"fatal", "reset", "flr", "general", "suggestion"};
339+
char level_str[FAULT_SHOW_STR_LEN + 1] = {0};
340+
u8 level;
341+
int err;
342+
343+
level = event->event.chip.err_level;
344+
if (level < FAULT_LEVEL_MAX)
345+
strncpy(level_str, fault_level[level], strlen(fault_level[level]));
346+
else
347+
strncpy(level_str, "Unknown", strlen("Unknown"));
348+
349+
if (level == FAULT_LEVEL_SERIOUS_FLR) {
350+
err = devlink_fmsg_u32_pair_put(fmsg, "Function level err func_id",
351+
(u32)event->event.chip.func_id);
352+
if (err)
353+
return err;
354+
}
355+
356+
err = devlink_fmsg_u8_pair_put(fmsg, "module_id", event->event.chip.node_id);
357+
if (err)
358+
return err;
359+
360+
err = devlink_fmsg_u32_pair_put(fmsg, "err_type", (u32)event->event.chip.err_type);
361+
if (err)
362+
return err;
363+
364+
err = devlink_fmsg_string_pair_put(fmsg, "err_level", level_str);
365+
if (err)
366+
return err;
367+
368+
err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_addr",
369+
event->event.chip.err_csr_addr);
370+
if (err)
371+
return err;
372+
373+
err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_value",
374+
event->event.chip.err_csr_value);
375+
if (err)
376+
return err;
377+
378+
return 0;
379+
}
380+
381+
static int fault_report_show(struct devlink_fmsg *fmsg,
382+
struct hinic_fault_event *event)
383+
{
384+
char fault_type[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
385+
"chip", "ucode", "mem rd timeout", "mem wr timeout",
386+
"reg rd timeout", "reg wr timeout", "phy fault"};
387+
char type_str[FAULT_SHOW_STR_LEN + 1] = {0};
388+
int err;
389+
390+
if (event->type < FAULT_TYPE_MAX)
391+
strncpy(type_str, fault_type[event->type], strlen(fault_type[event->type]));
392+
else
393+
strncpy(type_str, "Unknown", strlen("Unknown"));
394+
395+
err = devlink_fmsg_string_pair_put(fmsg, "Fault type", type_str);
396+
if (err)
397+
return err;
398+
399+
err = devlink_fmsg_binary_pair_put(fmsg, "Fault raw data",
400+
event->event.val, sizeof(event->event.val));
401+
if (err)
402+
return err;
403+
404+
switch (event->type) {
405+
case FAULT_TYPE_CHIP:
406+
err = chip_fault_show(fmsg, event);
407+
if (err)
408+
return err;
409+
break;
410+
case FAULT_TYPE_UCODE:
411+
err = devlink_fmsg_u8_pair_put(fmsg, "Cause_id", event->event.ucode.cause_id);
412+
if (err)
413+
return err;
414+
err = devlink_fmsg_u8_pair_put(fmsg, "core_id", event->event.ucode.core_id);
415+
if (err)
416+
return err;
417+
err = devlink_fmsg_u8_pair_put(fmsg, "c_id", event->event.ucode.c_id);
418+
if (err)
419+
return err;
420+
err = devlink_fmsg_u8_pair_put(fmsg, "epc", event->event.ucode.epc);
421+
if (err)
422+
return err;
423+
break;
424+
case FAULT_TYPE_MEM_RD_TIMEOUT:
425+
case FAULT_TYPE_MEM_WR_TIMEOUT:
426+
err = devlink_fmsg_u32_pair_put(fmsg, "Err_csr_ctrl",
427+
event->event.mem_timeout.err_csr_ctrl);
428+
if (err)
429+
return err;
430+
err = devlink_fmsg_u32_pair_put(fmsg, "err_csr_data",
431+
event->event.mem_timeout.err_csr_data);
432+
if (err)
433+
return err;
434+
err = devlink_fmsg_u32_pair_put(fmsg, "ctrl_tab",
435+
event->event.mem_timeout.ctrl_tab);
436+
if (err)
437+
return err;
438+
err = devlink_fmsg_u32_pair_put(fmsg, "mem_index",
439+
event->event.mem_timeout.mem_index);
440+
if (err)
441+
return err;
442+
break;
443+
case FAULT_TYPE_REG_RD_TIMEOUT:
444+
case FAULT_TYPE_REG_WR_TIMEOUT:
445+
err = devlink_fmsg_u32_pair_put(fmsg, "Err_csr", event->event.reg_timeout.err_csr);
446+
if (err)
447+
return err;
448+
break;
449+
case FAULT_TYPE_PHY_FAULT:
450+
err = devlink_fmsg_u8_pair_put(fmsg, "Op_type", event->event.phy_fault.op_type);
451+
if (err)
452+
return err;
453+
err = devlink_fmsg_u8_pair_put(fmsg, "port_id", event->event.phy_fault.port_id);
454+
if (err)
455+
return err;
456+
err = devlink_fmsg_u8_pair_put(fmsg, "dev_ad", event->event.phy_fault.dev_ad);
457+
if (err)
458+
return err;
459+
460+
err = devlink_fmsg_u32_pair_put(fmsg, "csr_addr", event->event.phy_fault.csr_addr);
461+
if (err)
462+
return err;
463+
err = devlink_fmsg_u32_pair_put(fmsg, "op_data", event->event.phy_fault.op_data);
464+
if (err)
465+
return err;
466+
break;
467+
default:
468+
break;
469+
}
470+
471+
return 0;
472+
}
473+
474+
static int hinic_hw_reporter_dump(struct devlink_health_reporter *reporter,
475+
struct devlink_fmsg *fmsg, void *priv_ctx,
476+
struct netlink_ext_ack *extack)
477+
{
478+
if (priv_ctx)
479+
return fault_report_show(fmsg, priv_ctx);
480+
481+
return 0;
482+
}
483+
484+
static int mgmt_watchdog_report_show(struct devlink_fmsg *fmsg,
485+
struct hinic_mgmt_watchdog_info *watchdog_info)
486+
{
487+
int err;
488+
489+
err = devlink_fmsg_u32_pair_put(fmsg, "Mgmt deadloop time_h", watchdog_info->curr_time_h);
490+
if (err)
491+
return err;
492+
493+
err = devlink_fmsg_u32_pair_put(fmsg, "time_l", watchdog_info->curr_time_l);
494+
if (err)
495+
return err;
496+
497+
err = devlink_fmsg_u32_pair_put(fmsg, "task_id", watchdog_info->task_id);
498+
if (err)
499+
return err;
500+
501+
err = devlink_fmsg_u32_pair_put(fmsg, "sp", watchdog_info->sp);
502+
if (err)
503+
return err;
504+
505+
err = devlink_fmsg_u32_pair_put(fmsg, "stack_current_used", watchdog_info->curr_used);
506+
if (err)
507+
return err;
508+
509+
err = devlink_fmsg_u32_pair_put(fmsg, "peak_used", watchdog_info->peak_used);
510+
if (err)
511+
return err;
512+
513+
err = devlink_fmsg_u32_pair_put(fmsg, "\n Overflow_flag", watchdog_info->is_overflow);
514+
if (err)
515+
return err;
516+
517+
err = devlink_fmsg_u32_pair_put(fmsg, "stack_top", watchdog_info->stack_top);
518+
if (err)
519+
return err;
520+
521+
err = devlink_fmsg_u32_pair_put(fmsg, "stack_bottom", watchdog_info->stack_bottom);
522+
if (err)
523+
return err;
524+
525+
err = devlink_fmsg_u32_pair_put(fmsg, "mgmt_pc", watchdog_info->pc);
526+
if (err)
527+
return err;
528+
529+
err = devlink_fmsg_u32_pair_put(fmsg, "lr", watchdog_info->lr);
530+
if (err)
531+
return err;
532+
533+
err = devlink_fmsg_u32_pair_put(fmsg, "cpsr", watchdog_info->cpsr);
534+
if (err)
535+
return err;
536+
537+
err = devlink_fmsg_binary_pair_put(fmsg, "Mgmt register info",
538+
watchdog_info->reg, sizeof(watchdog_info->reg));
539+
if (err)
540+
return err;
541+
542+
err = devlink_fmsg_binary_pair_put(fmsg, "Mgmt dump stack(start from sp)",
543+
watchdog_info->data, sizeof(watchdog_info->data));
544+
if (err)
545+
return err;
546+
547+
return 0;
548+
}
549+
550+
static int hinic_fw_reporter_dump(struct devlink_health_reporter *reporter,
551+
struct devlink_fmsg *fmsg, void *priv_ctx,
552+
struct netlink_ext_ack *extack)
553+
{
554+
if (priv_ctx)
555+
return mgmt_watchdog_report_show(fmsg, priv_ctx);
556+
557+
return 0;
558+
}
559+
560+
static const struct devlink_health_reporter_ops hinic_hw_fault_reporter_ops = {
561+
.name = "hw",
562+
.dump = hinic_hw_reporter_dump,
563+
};
564+
565+
static const struct devlink_health_reporter_ops hinic_fw_fault_reporter_ops = {
566+
.name = "fw",
567+
.dump = hinic_fw_reporter_dump,
568+
};
569+
570+
int hinic_health_reporters_create(struct hinic_devlink_priv *priv)
571+
{
572+
struct devlink *devlink = priv_to_devlink(priv);
573+
574+
priv->hw_fault_reporter =
575+
devlink_health_reporter_create(devlink, &hinic_hw_fault_reporter_ops,
576+
0, priv);
577+
if (IS_ERR(priv->hw_fault_reporter)) {
578+
dev_warn(&priv->hwdev->hwif->pdev->dev, "Failed to create hw fault reporter, err: %ld\n",
579+
PTR_ERR(priv->hw_fault_reporter));
580+
return PTR_ERR(priv->hw_fault_reporter);
581+
}
582+
583+
priv->fw_fault_reporter =
584+
devlink_health_reporter_create(devlink, &hinic_fw_fault_reporter_ops,
585+
0, priv);
586+
if (IS_ERR(priv->fw_fault_reporter)) {
587+
dev_warn(&priv->hwdev->hwif->pdev->dev, "Failed to create fw fault reporter, err: %ld\n",
588+
PTR_ERR(priv->fw_fault_reporter));
589+
devlink_health_reporter_destroy(priv->hw_fault_reporter);
590+
priv->hw_fault_reporter = NULL;
591+
return PTR_ERR(priv->fw_fault_reporter);
592+
}
593+
594+
return 0;
595+
}
596+
597+
void hinic_health_reporters_destroy(struct hinic_devlink_priv *priv)
598+
{
599+
if (!IS_ERR_OR_NULL(priv->fw_fault_reporter)) {
600+
devlink_health_reporter_destroy(priv->fw_fault_reporter);
601+
priv->fw_fault_reporter = NULL;
602+
}
603+
604+
if (!IS_ERR_OR_NULL(priv->hw_fault_reporter)) {
605+
devlink_health_reporter_destroy(priv->hw_fault_reporter);
606+
priv->hw_fault_reporter = NULL;
607+
}
608+
}

drivers/net/ethernet/huawei/hinic/hinic_devlink.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define __HINIC_DEVLINK_H__
88

99
#include <net/devlink.h>
10+
#include "hinic_dev.h"
1011

1112
#define MAX_FW_TYPE_NUM 30
1213
#define HINIC_MAGIC_NUM 0x18221100
@@ -109,7 +110,10 @@ struct host_image_st {
109110

110111
struct devlink *hinic_devlink_alloc(void);
111112
void hinic_devlink_free(struct devlink *devlink);
112-
int hinic_devlink_register(struct devlink *devlink, struct device *dev);
113-
void hinic_devlink_unregister(struct devlink *devlink);
113+
int hinic_devlink_register(struct hinic_devlink_priv *priv, struct device *dev);
114+
void hinic_devlink_unregister(struct hinic_devlink_priv *priv);
115+
116+
int hinic_health_reporters_create(struct hinic_devlink_priv *priv);
117+
void hinic_health_reporters_destroy(struct hinic_devlink_priv *priv);
114118

115119
#endif /* __HINIC_DEVLINK_H__ */

drivers/net/ethernet/huawei/hinic/hinic_ethtool.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,25 @@ static int hinic_get_module_eeprom(struct net_device *netdev,
17661766
return 0;
17671767
}
17681768

1769+
static int
1770+
hinic_get_link_ext_state(struct net_device *netdev,
1771+
struct ethtool_link_ext_state_info *link_ext_state_info)
1772+
{
1773+
struct hinic_dev *nic_dev = netdev_priv(netdev);
1774+
1775+
if (netif_carrier_ok(netdev))
1776+
return -ENODATA;
1777+
1778+
if (nic_dev->cable_unplugged)
1779+
link_ext_state_info->link_ext_state =
1780+
ETHTOOL_LINK_EXT_STATE_NO_CABLE;
1781+
else if (nic_dev->module_unrecognized)
1782+
link_ext_state_info->link_ext_state =
1783+
ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH;
1784+
1785+
return 0;
1786+
}
1787+
17691788
static const struct ethtool_ops hinic_ethtool_ops = {
17701789
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
17711790
ETHTOOL_COALESCE_RX_MAX_FRAMES |
@@ -1776,6 +1795,7 @@ static const struct ethtool_ops hinic_ethtool_ops = {
17761795
.set_link_ksettings = hinic_set_link_ksettings,
17771796
.get_drvinfo = hinic_get_drvinfo,
17781797
.get_link = ethtool_op_get_link,
1798+
.get_link_ext_state = hinic_get_link_ext_state,
17791799
.get_ringparam = hinic_get_ringparam,
17801800
.set_ringparam = hinic_set_ringparam,
17811801
.get_coalesce = hinic_get_coalesce,

0 commit comments

Comments
 (0)