Skip to content

Commit 22f5dba

Browse files
vikasbrcmdavem330
authored andcommitted
bnxt_en: add an nvm test for hw diagnose
Add an NVM test function for devlink hw reporter. In this function an NVM VPD area is read followed by a write. Test result is cached and if it is successful then the next test can be conducted only after HW_RETEST_MIN_TIME to avoid frequent writes to the NVM. Reviewed-by: Edwin Peer <[email protected]> Signed-off-by: Vikas Gupta <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bafed3f commit 22f5dba

File tree

4 files changed

+113
-18
lines changed

4 files changed

+113
-18
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,17 +1544,29 @@ struct bnxt_ctx_mem_info {
15441544
};
15451545

15461546
enum bnxt_hw_err {
1547-
BNXT_HW_STATUS_HEALTHY = 0x0,
1548-
BNXT_HW_STATUS_NVM_WRITE_ERR = 0x1,
1549-
BNXT_HW_STATUS_NVM_ERASE_ERR = 0x2,
1550-
BNXT_HW_STATUS_NVM_UNKNOWN_ERR = 0x3,
1547+
BNXT_HW_STATUS_HEALTHY = 0x0,
1548+
BNXT_HW_STATUS_NVM_WRITE_ERR = 0x1,
1549+
BNXT_HW_STATUS_NVM_ERASE_ERR = 0x2,
1550+
BNXT_HW_STATUS_NVM_UNKNOWN_ERR = 0x3,
1551+
BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR = 0x4,
1552+
BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR = 0x5,
1553+
BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR = 0x6,
1554+
BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR = 0x7,
15511555
};
15521556

15531557
struct bnxt_hw_health {
15541558
u32 nvm_err_address;
15551559
u32 nvm_write_errors;
15561560
u32 nvm_erase_errors;
1561+
u32 nvm_test_vpd_ent_errors;
1562+
u32 nvm_test_vpd_read_errors;
1563+
u32 nvm_test_vpd_write_errors;
1564+
u32 nvm_test_incmpl_errors;
15571565
u8 synd;
1566+
/* max a test in a day if previous test was successful */
1567+
#define HW_RETEST_MIN_TIME (1000 * 3600 * 24)
1568+
u8 nvm_test_result;
1569+
unsigned long nvm_test_timestamp;
15581570
struct devlink_health_reporter *hw_reporter;
15591571
};
15601572

drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "bnxt_ulp.h"
2121
#include "bnxt_ptp.h"
2222
#include "bnxt_coredump.h"
23+
#include "bnxt_nvm_defs.h" /* NVRAM content constant and structure defs */
2324

2425
static void __bnxt_fw_recover(struct bnxt *bp)
2526
{
@@ -263,20 +264,82 @@ static const char *hw_err_str(u8 synd)
263264
return "nvm erase error";
264265
case BNXT_HW_STATUS_NVM_UNKNOWN_ERR:
265266
return "unrecognized nvm error";
267+
case BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR:
268+
return "nvm test vpd entry error";
269+
case BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR:
270+
return "nvm test vpd read error";
271+
case BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR:
272+
return "nvm test vpd write error";
273+
case BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR:
274+
return "nvm test incomplete error";
266275
default:
267276
return "unknown hw error";
268277
}
269278
}
270279

280+
static void bnxt_nvm_test(struct bnxt *bp)
281+
{
282+
struct bnxt_hw_health *h = &bp->hw_health;
283+
u32 datalen;
284+
u16 index;
285+
u8 *buf;
286+
287+
if (!h->nvm_test_result) {
288+
if (!h->nvm_test_timestamp ||
289+
time_after(jiffies, h->nvm_test_timestamp +
290+
msecs_to_jiffies(HW_RETEST_MIN_TIME)))
291+
h->nvm_test_timestamp = jiffies;
292+
else
293+
return;
294+
}
295+
296+
if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD,
297+
BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
298+
&index, NULL, &datalen) || !datalen) {
299+
h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR;
300+
h->nvm_test_vpd_ent_errors++;
301+
return;
302+
}
303+
304+
buf = kzalloc(datalen, GFP_KERNEL);
305+
if (!buf) {
306+
h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR;
307+
h->nvm_test_incmpl_errors++;
308+
return;
309+
}
310+
311+
if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
312+
h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR;
313+
h->nvm_test_vpd_read_errors++;
314+
goto err;
315+
}
316+
317+
if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
318+
BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
319+
h->nvm_test_result = BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR;
320+
h->nvm_test_vpd_write_errors++;
321+
}
322+
323+
err:
324+
kfree(buf);
325+
}
326+
271327
static int bnxt_hw_diagnose(struct devlink_health_reporter *reporter,
272328
struct devlink_fmsg *fmsg,
273329
struct netlink_ext_ack *extack)
274330
{
275331
struct bnxt *bp = devlink_health_reporter_priv(reporter);
276332
struct bnxt_hw_health *h = &bp->hw_health;
333+
u8 synd = h->synd;
277334
int rc;
278335

279-
rc = devlink_fmsg_string_pair_put(fmsg, "Status", hw_err_str(h->synd));
336+
bnxt_nvm_test(bp);
337+
if (h->nvm_test_result) {
338+
synd = h->nvm_test_result;
339+
devlink_health_report(h->hw_reporter, hw_err_str(synd), NULL);
340+
}
341+
342+
rc = devlink_fmsg_string_pair_put(fmsg, "Status", hw_err_str(synd));
280343
if (rc)
281344
return rc;
282345
rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_write_errors", h->nvm_write_errors);
@@ -285,6 +348,23 @@ static int bnxt_hw_diagnose(struct devlink_health_reporter *reporter,
285348
rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_erase_errors", h->nvm_erase_errors);
286349
if (rc)
287350
return rc;
351+
rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_vpd_ent_errors",
352+
h->nvm_test_vpd_ent_errors);
353+
if (rc)
354+
return rc;
355+
rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_vpd_read_errors",
356+
h->nvm_test_vpd_read_errors);
357+
if (rc)
358+
return rc;
359+
rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_vpd_write_errors",
360+
h->nvm_test_vpd_write_errors);
361+
if (rc)
362+
return rc;
363+
rc = devlink_fmsg_u32_pair_put(fmsg, "nvm_test_incomplete_errors",
364+
h->nvm_test_incmpl_errors);
365+
if (rc)
366+
return rc;
367+
288368
return 0;
289369
}
290370

drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,14 +2168,10 @@ static void bnxt_print_admin_err(struct bnxt *bp)
21682168
netdev_info(bp->dev, "PF does not have admin privileges to flash or reset the device\n");
21692169
}
21702170

2171-
static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2172-
u16 ext, u16 *index, u32 *item_length,
2173-
u32 *data_length);
2174-
2175-
static int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
2176-
u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
2177-
u32 dir_item_len, const u8 *data,
2178-
size_t data_len)
2171+
int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
2172+
u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
2173+
u32 dir_item_len, const u8 *data,
2174+
size_t data_len)
21792175
{
21802176
struct bnxt *bp = netdev_priv(dev);
21812177
struct hwrm_nvm_write_input *req;
@@ -2819,8 +2815,8 @@ static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data)
28192815
return rc;
28202816
}
28212817

2822-
static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
2823-
u32 length, u8 *data)
2818+
int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
2819+
u32 length, u8 *data)
28242820
{
28252821
struct bnxt *bp = netdev_priv(dev);
28262822
int rc;
@@ -2854,9 +2850,9 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
28542850
return rc;
28552851
}
28562852

2857-
static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2858-
u16 ext, u16 *index, u32 *item_length,
2859-
u32 *data_length)
2853+
int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2854+
u16 ext, u16 *index, u32 *item_length,
2855+
u32 *data_length)
28602856
{
28612857
struct hwrm_nvm_find_dir_entry_output *output;
28622858
struct hwrm_nvm_find_dir_entry_input *req;

drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ int bnxt_hwrm_firmware_reset(struct net_device *dev, u8 proc_type,
5656
int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
5757
u32 install_type);
5858
int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size);
59+
int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal, u16 ext,
60+
u16 *index, u32 *item_length, u32 *data_length);
61+
int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
62+
u32 length, u8 *data);
63+
int bnxt_flash_nvram(struct net_device *dev, u16 dir_type, u16 dir_ordinal,
64+
u16 dir_ext, u16 dir_attr, u32 dir_item_len,
65+
const u8 *data, size_t data_len);
5966
void bnxt_ethtool_init(struct bnxt *bp);
6067
void bnxt_ethtool_free(struct bnxt *bp);
6168

0 commit comments

Comments
 (0)