From a5722300aaf495489ab5ce115f8955915a4dcb70 Mon Sep 17 00:00:00 2001 From: Jonathan Toppins Date: Wed, 2 Oct 2019 18:23:26 -0400 Subject: [PATCH 71/96] [netdrv] bnxt_en: Add new FW devlink_health_reporter Message-id: <54406dbbfa698feebe5b59a0c650fe80f3bd751c.1570027456.git.jtoppins@redhat.com> Patchwork-id: 276493 O-Subject: [RHEL-8.2 PATCH 64/78] bnxt_en: Add new FW devlink_health_reporter Bugzilla: 1724766 RH-Acked-by: John Linville RH-Acked-by: Jarod Wilson Create new FW devlink_health_reporter, to know the current health status of FW. Command example and output: $ devlink health show pci/0000:af:00.0 reporter fw pci/0000:af:00.0: name fw state healthy error 0 recover 0 FW status: Healthy; Reset count: 1 Cc: Jiri Pirko Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller (cherry picked from commit 6763c779c2d8b568b2e174f3eeeaf644fa38b34d) Bugzilla: 1724766 Build Info: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23809532 Tested: build, boot, basic ping Signed-off-by: Jonathan Toppins Signed-off-by: Bruno Meneguele --- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 3 + drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 81 +++++++++++++++++++++++ 2 files changed, 84 insertions(+) Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt.h =================================================================== --- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2020-02-06 16:23:19.750476068 +0100 +++ src/drivers/net/ethernet/broadcom/bnxt/bnxt.h 2020-02-06 16:23:19.896474728 +0100 @@ -1368,6 +1368,7 @@ u32 fw_reset_seq_regs[16]; u32 fw_reset_seq_vals[16]; u32 fw_reset_seq_delay_msec[16]; + struct devlink_health_reporter *fw_reporter; }; #define BNXT_FW_HEALTH_REG_TYPE_MASK 3 @@ -1382,6 +1383,8 @@ #define BNXT_FW_HEALTH_WIN_BASE 0x3000 #define BNXT_FW_HEALTH_WIN_MAP_OFF 8 +#define BNXT_FW_STATUS_HEALTHY 0x8000 + struct bnxt { void __iomem *bar0; void __iomem *bar1; Index: src/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c =================================================================== --- src.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c 2020-02-06 16:23:18.306489323 +0100 +++ src/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c 2020-02-06 16:23:19.896474728 +0100 @@ -15,6 +15,84 @@ #include "bnxt_vfr.h" #include "bnxt_devlink.h" +static int bnxt_fw_reporter_diagnose(struct devlink_health_reporter *reporter, + struct devlink_fmsg *fmsg) +{ + struct bnxt *bp = devlink_health_reporter_priv(reporter); + struct bnxt_fw_health *health = bp->fw_health; + u32 val, health_status; + int rc; + + if (!health || test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) + return 0; + + val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); + health_status = val & 0xffff; + + if (health_status == BNXT_FW_STATUS_HEALTHY) { + rc = devlink_fmsg_string_pair_put(fmsg, "FW status", + "Healthy;"); + if (rc) + return rc; + } else if (health_status < BNXT_FW_STATUS_HEALTHY) { + rc = devlink_fmsg_string_pair_put(fmsg, "FW status", + "Not yet completed initialization;"); + if (rc) + return rc; + } else if (health_status > BNXT_FW_STATUS_HEALTHY) { + rc = devlink_fmsg_string_pair_put(fmsg, "FW status", + "Encountered fatal error and cannot recover;"); + if (rc) + return rc; + } + + if (val >> 16) { + rc = devlink_fmsg_u32_pair_put(fmsg, "Error", val >> 16); + if (rc) + return rc; + } + + val = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG); + rc = devlink_fmsg_u32_pair_put(fmsg, "Reset count", val); + if (rc) + return rc; + + return 0; +} + +static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = { + .name = "fw", + .diagnose = bnxt_fw_reporter_diagnose, +}; + +static void bnxt_dl_fw_reporters_create(struct bnxt *bp) +{ + struct bnxt_fw_health *health = bp->fw_health; + + if (!health) + return; + + health->fw_reporter = + devlink_health_reporter_create(bp->dl, &bnxt_dl_fw_reporter_ops, + 0, false, bp); + if (IS_ERR(health->fw_reporter)) { + netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n", + PTR_ERR(health->fw_reporter)); + health->fw_reporter = NULL; + } +} + +static void bnxt_dl_fw_reporters_destroy(struct bnxt *bp) +{ + struct bnxt_fw_health *health = bp->fw_health; + + if (!health) + return; + + if (health->fw_reporter) + devlink_health_reporter_destroy(health->fw_reporter); +} + static const struct devlink_ops bnxt_dl_ops = { #ifdef CONFIG_BNXT_SRIOV .eswitch_mode_set = bnxt_dl_eswitch_mode_set, @@ -246,6 +324,8 @@ devlink_params_publish(dl); + bnxt_dl_fw_reporters_create(bp); + return 0; err_dl_port_unreg: @@ -268,6 +348,7 @@ if (!dl) return; + bnxt_dl_fw_reporters_destroy(bp); devlink_port_params_unregister(&bp->dl_port, bnxt_dl_port_params, ARRAY_SIZE(bnxt_dl_port_params)); devlink_port_unregister(&bp->dl_port);