]> git.baikalelectronics.ru Git - kernel.git/commitdiff
bnxt_en: Add devlink health reset reporter.
authorVasundhara Volam <vasundhara-v.volam@broadcom.com>
Fri, 30 Aug 2019 03:55:00 +0000 (23:55 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 30 Aug 2019 21:02:19 +0000 (14:02 -0700)
Add devlink health reporter for the firmware reset event.  Once we get
the notification from firmware about the impending reset, the driver
will report this to devlink and the call to bnxt_fw_reset() will be
initiated to complete the reset sequence.

Cc: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h

index 98b155514cc5088a9575a1459856eab04ecb193d..cd20067fff05b91e376e6b74af09c553756f6919 100644 (file)
@@ -10167,6 +10167,9 @@ static void bnxt_sp_task(struct work_struct *work)
        if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event))
                bnxt_reset(bp, true);
 
+       if (test_and_clear_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event))
+               bnxt_devlink_health_report(bp, BNXT_FW_RESET_NOTIFY_SP_EVENT);
+
        smp_mb__before_atomic();
        clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
 }
index c78aa51f572f43780278368e8f185fe7cbc5b6fe..d65625fc31835bfb42c821dab011c7ae343f2e85 100644 (file)
@@ -1371,6 +1371,11 @@ struct bnxt_fw_health {
        u32 fw_reset_seq_vals[16];
        u32 fw_reset_seq_delay_msec[16];
        struct devlink_health_reporter  *fw_reporter;
+       struct devlink_health_reporter *fw_reset_reporter;
+};
+
+struct bnxt_fw_reporter_ctx {
+       unsigned long sp_event;
 };
 
 #define BNXT_FW_HEALTH_REG_TYPE_MASK   3
index e15d5dc78725c6c13cd6a2e97bfa81132008cf9c..8512467c2134513e844cacc1ad7e39fb48b4d39e 100644 (file)
@@ -65,6 +65,24 @@ static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = {
        .diagnose = bnxt_fw_reporter_diagnose,
 };
 
+static int bnxt_fw_reset_recover(struct devlink_health_reporter *reporter,
+                                void *priv_ctx)
+{
+       struct bnxt *bp = devlink_health_reporter_priv(reporter);
+
+       if (!priv_ctx)
+               return -EOPNOTSUPP;
+
+       bnxt_fw_reset(bp);
+       return 0;
+}
+
+static const
+struct devlink_health_reporter_ops bnxt_dl_fw_reset_reporter_ops = {
+       .name = "fw_reset",
+       .recover = bnxt_fw_reset_recover,
+};
+
 static void bnxt_dl_fw_reporters_create(struct bnxt *bp)
 {
        struct bnxt_fw_health *health = bp->fw_health;
@@ -80,6 +98,16 @@ static void bnxt_dl_fw_reporters_create(struct bnxt *bp)
                            PTR_ERR(health->fw_reporter));
                health->fw_reporter = NULL;
        }
+
+       health->fw_reset_reporter =
+               devlink_health_reporter_create(bp->dl,
+                                              &bnxt_dl_fw_reset_reporter_ops,
+                                              0, true, bp);
+       if (IS_ERR(health->fw_reset_reporter)) {
+               netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",
+                           PTR_ERR(health->fw_reset_reporter));
+               health->fw_reset_reporter = NULL;
+       }
 }
 
 static void bnxt_dl_fw_reporters_destroy(struct bnxt *bp)
@@ -91,6 +119,30 @@ static void bnxt_dl_fw_reporters_destroy(struct bnxt *bp)
 
        if (health->fw_reporter)
                devlink_health_reporter_destroy(health->fw_reporter);
+
+       if (health->fw_reset_reporter)
+               devlink_health_reporter_destroy(health->fw_reset_reporter);
+}
+
+void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event)
+{
+       struct bnxt_fw_health *fw_health = bp->fw_health;
+       struct bnxt_fw_reporter_ctx fw_reporter_ctx;
+
+       if (!fw_health)
+               return;
+
+       fw_reporter_ctx.sp_event = event;
+       switch (event) {
+       case BNXT_FW_RESET_NOTIFY_SP_EVENT:
+               if (!fw_health->fw_reset_reporter)
+                       return;
+
+               devlink_health_report(fw_health->fw_reset_reporter,
+                                     "FW non-fatal reset event received",
+                                     &fw_reporter_ctx);
+               return;
+       }
 }
 
 static const struct devlink_ops bnxt_dl_ops = {
index 5b6b2c7d97cfadee3644d44ff6cce32caffeaa3e..b97e0baeb42d6b2a07d9af7770e551429b90df1b 100644 (file)
@@ -55,6 +55,7 @@ struct bnxt_dl_nvm_param {
        u16 num_bits;
 };
 
+void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event);
 int bnxt_dl_register(struct bnxt *bp);
 void bnxt_dl_unregister(struct bnxt *bp);