bnxt_en: implement callbacks for devlink selftests
authorvikas <vikas.gupta@broadcom.com>
Wed, 27 Jul 2022 16:57:21 +0000 (22:27 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 29 Jul 2022 04:56:53 +0000 (21:56 -0700)
Add callbacks
=============
.selftest_check: returns true for flash selftest.
.selftest_run: runs a flash selftest.

Also, refactor NVM APIs so that they can be
used with devlink and ethtool both.

Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h

index 6b3d4f4..14df8cf 100644 (file)
@@ -20,6 +20,8 @@
 #include "bnxt_ulp.h"
 #include "bnxt_ptp.h"
 #include "bnxt_coredump.h"
+#include "bnxt_nvm_defs.h"
+#include "bnxt_ethtool.h"
 
 static void __bnxt_fw_recover(struct bnxt *bp)
 {
@@ -610,6 +612,63 @@ static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action acti
        return rc;
 }
 
+static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
+{
+       u32 datalen;
+       u16 index;
+       u8 *buf;
+
+       if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD,
+                                BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
+                                &index, NULL, &datalen) || !datalen) {
+               NL_SET_ERR_MSG_MOD(extack, "nvm test vpd entry error");
+               return false;
+       }
+
+       buf = kzalloc(datalen, GFP_KERNEL);
+       if (!buf) {
+               NL_SET_ERR_MSG_MOD(extack, "insufficient memory for nvm test");
+               return false;
+       }
+
+       if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
+               NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
+               goto err;
+       }
+
+       if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
+                            BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
+               NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
+               goto err;
+       }
+
+       return true;
+
+err:
+       kfree(buf);
+       return false;
+}
+
+static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
+                                  struct netlink_ext_ack *extack)
+{
+       return id == DEVLINK_ATTR_SELFTEST_ID_FLASH;
+}
+
+static enum devlink_selftest_status bnxt_dl_selftest_run(struct devlink *dl,
+                                                        unsigned int id,
+                                                        struct netlink_ext_ack *extack)
+{
+       struct bnxt *bp = bnxt_get_bp_from_dl(dl);
+
+       if (id == DEVLINK_ATTR_SELFTEST_ID_FLASH)
+               return bnxt_nvm_test(bp, extack) ?
+                               DEVLINK_SELFTEST_STATUS_PASS :
+                               DEVLINK_SELFTEST_STATUS_FAIL;
+
+       return DEVLINK_SELFTEST_STATUS_SKIP;
+}
+
 static const struct devlink_ops bnxt_dl_ops = {
 #ifdef CONFIG_BNXT_SRIOV
        .eswitch_mode_set = bnxt_dl_eswitch_mode_set,
@@ -622,6 +681,8 @@ static const struct devlink_ops bnxt_dl_ops = {
        .reload_limits    = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
        .reload_down      = bnxt_dl_reload_down,
        .reload_up        = bnxt_dl_reload_up,
+       .selftest_check   = bnxt_dl_selftest_check,
+       .selftest_run     = bnxt_dl_selftest_run,
 };
 
 static const struct devlink_ops bnxt_vf_dl_ops;
index 7191e5d..87eb536 100644 (file)
@@ -2176,14 +2176,14 @@ static void bnxt_print_admin_err(struct bnxt *bp)
        netdev_info(bp->dev, "PF does not have admin privileges to flash or reset the device\n");
 }
 
-static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
-                               u16 ext, u16 *index, u32 *item_length,
-                               u32 *data_length);
+int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
+                        u16 ext, u16 *index, u32 *item_length,
+                        u32 *data_length);
 
-static int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
-                           u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
-                           u32 dir_item_len, const u8 *data,
-                           size_t data_len)
+int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
+                    u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
+                    u32 dir_item_len, const u8 *data,
+                    size_t data_len)
 {
        struct bnxt *bp = netdev_priv(dev);
        struct hwrm_nvm_write_input *req;
@@ -2836,8 +2836,8 @@ static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data)
        return rc;
 }
 
-static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
-                              u32 length, u8 *data)
+int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
+                       u32 length, u8 *data)
 {
        struct bnxt *bp = netdev_priv(dev);
        int rc;
@@ -2871,9 +2871,9 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
        return rc;
 }
 
-static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
-                               u16 ext, u16 *index, u32 *item_length,
-                               u32 *data_length)
+int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
+                        u16 ext, u16 *index, u32 *item_length,
+                        u32 *data_length)
 {
        struct hwrm_nvm_find_dir_entry_output *output;
        struct hwrm_nvm_find_dir_entry_input *req;
index a592842..a8ecef8 100644 (file)
@@ -58,5 +58,17 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
 int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size);
 void bnxt_ethtool_init(struct bnxt *bp);
 void bnxt_ethtool_free(struct bnxt *bp);
+int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
+                        u16 ext, u16 *index, u32 *item_length,
+                        u32 *data_length);
+int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
+                        u16 ext, u16 *index, u32 *item_length,
+                        u32 *data_length);
+int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
+                    u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
+                    u32 dir_item_len, const u8 *data,
+                    size_t data_len);
+int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
+                       u32 length, u8 *data);
 
 #endif