Skip to content

Commit 1515a1b

Browse files
committed
Merge branch 'add-framework-for-selftests-in-devlink'
Vikas Gupta says: ==================== add framework for selftests in devlink Add support for selftests in the devlink framework. Adds a callback .selftests_check and .selftests_run in devlink_ops. User can add test(s) suite which is subsequently passed to the driver and driver can opt for running particular tests based on its capabilities. Patchset adds a flash based test for the bnxt_en driver. ==================== Link: https://lore.kernel.org/r/20220727165721.37959-1-vikas.gupta@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 68be7b8 + 5b6ff12 commit 1515a1b

File tree

7 files changed

+389
-12
lines changed

7 files changed

+389
-12
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
3+
=================
4+
Devlink Selftests
5+
=================
6+
7+
The ``devlink-selftests`` API allows executing selftests on the device.
8+
9+
Tests Mask
10+
==========
11+
The ``devlink-selftests`` command should be run with a mask indicating
12+
the tests to be executed.
13+
14+
Tests Description
15+
=================
16+
The following is a list of tests that drivers may execute.
17+
18+
.. list-table:: List of tests
19+
:widths: 5 90
20+
21+
* - Name
22+
- Description
23+
* - ``DEVLINK_SELFTEST_FLASH``
24+
- Devices may have the firmware on non-volatile memory on the board, e.g.
25+
flash. This particular test helps to run a flash selftest on the device.
26+
Implementation of the test is left to the driver/firmware.
27+
28+
example usage
29+
-------------
30+
31+
.. code:: shell
32+
33+
# Query selftests supported on the devlink device
34+
$ devlink dev selftests show DEV
35+
# Query selftests supported on all devlink devices
36+
$ devlink dev selftests show
37+
# Executes selftests on the device
38+
$ devlink dev selftests run DEV id flash

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

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "bnxt_ulp.h"
2121
#include "bnxt_ptp.h"
2222
#include "bnxt_coredump.h"
23+
#include "bnxt_nvm_defs.h"
24+
#include "bnxt_ethtool.h"
2325

2426
static void __bnxt_fw_recover(struct bnxt *bp)
2527
{
@@ -610,6 +612,63 @@ static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action acti
610612
return rc;
611613
}
612614

615+
static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
616+
{
617+
u32 datalen;
618+
u16 index;
619+
u8 *buf;
620+
621+
if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD,
622+
BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
623+
&index, NULL, &datalen) || !datalen) {
624+
NL_SET_ERR_MSG_MOD(extack, "nvm test vpd entry error");
625+
return false;
626+
}
627+
628+
buf = kzalloc(datalen, GFP_KERNEL);
629+
if (!buf) {
630+
NL_SET_ERR_MSG_MOD(extack, "insufficient memory for nvm test");
631+
return false;
632+
}
633+
634+
if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
635+
NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
636+
goto err;
637+
}
638+
639+
if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
640+
BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
641+
NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
642+
goto err;
643+
}
644+
645+
return true;
646+
647+
err:
648+
kfree(buf);
649+
return false;
650+
}
651+
652+
static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
653+
struct netlink_ext_ack *extack)
654+
{
655+
return id == DEVLINK_ATTR_SELFTEST_ID_FLASH;
656+
}
657+
658+
static enum devlink_selftest_status bnxt_dl_selftest_run(struct devlink *dl,
659+
unsigned int id,
660+
struct netlink_ext_ack *extack)
661+
{
662+
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
663+
664+
if (id == DEVLINK_ATTR_SELFTEST_ID_FLASH)
665+
return bnxt_nvm_test(bp, extack) ?
666+
DEVLINK_SELFTEST_STATUS_PASS :
667+
DEVLINK_SELFTEST_STATUS_FAIL;
668+
669+
return DEVLINK_SELFTEST_STATUS_SKIP;
670+
}
671+
613672
static const struct devlink_ops bnxt_dl_ops = {
614673
#ifdef CONFIG_BNXT_SRIOV
615674
.eswitch_mode_set = bnxt_dl_eswitch_mode_set,
@@ -622,6 +681,8 @@ static const struct devlink_ops bnxt_dl_ops = {
622681
.reload_limits = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
623682
.reload_down = bnxt_dl_reload_down,
624683
.reload_up = bnxt_dl_reload_up,
684+
.selftest_check = bnxt_dl_selftest_check,
685+
.selftest_run = bnxt_dl_selftest_run,
625686
};
626687

627688
static const struct devlink_ops bnxt_vf_dl_ops;

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,14 +2176,14 @@ static void bnxt_print_admin_err(struct bnxt *bp)
21762176
netdev_info(bp->dev, "PF does not have admin privileges to flash or reset the device\n");
21772177
}
21782178

2179-
static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2180-
u16 ext, u16 *index, u32 *item_length,
2181-
u32 *data_length);
2179+
int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2180+
u16 ext, u16 *index, u32 *item_length,
2181+
u32 *data_length);
21822182

2183-
static int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
2184-
u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
2185-
u32 dir_item_len, const u8 *data,
2186-
size_t data_len)
2183+
int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
2184+
u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
2185+
u32 dir_item_len, const u8 *data,
2186+
size_t data_len)
21872187
{
21882188
struct bnxt *bp = netdev_priv(dev);
21892189
struct hwrm_nvm_write_input *req;
@@ -2836,8 +2836,8 @@ static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data)
28362836
return rc;
28372837
}
28382838

2839-
static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
2840-
u32 length, u8 *data)
2839+
int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
2840+
u32 length, u8 *data)
28412841
{
28422842
struct bnxt *bp = netdev_priv(dev);
28432843
int rc;
@@ -2871,9 +2871,9 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
28712871
return rc;
28722872
}
28732873

2874-
static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2875-
u16 ext, u16 *index, u32 *item_length,
2876-
u32 *data_length)
2874+
int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
2875+
u16 ext, u16 *index, u32 *item_length,
2876+
u32 *data_length)
28772877
{
28782878
struct hwrm_nvm_find_dir_entry_output *output;
28792879
struct hwrm_nvm_find_dir_entry_input *req;

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,17 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
5858
int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size);
5959
void bnxt_ethtool_init(struct bnxt *bp);
6060
void bnxt_ethtool_free(struct bnxt *bp);
61+
int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
62+
u16 ext, u16 *index, u32 *item_length,
63+
u32 *data_length);
64+
int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
65+
u16 ext, u16 *index, u32 *item_length,
66+
u32 *data_length);
67+
int bnxt_flash_nvram(struct net_device *dev, u16 dir_type,
68+
u16 dir_ordinal, u16 dir_ext, u16 dir_attr,
69+
u32 dir_item_len, const u8 *data,
70+
size_t data_len);
71+
int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
72+
u32 length, u8 *data);
6173

6274
#endif

include/net/devlink.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,27 @@ struct devlink_ops {
15091509
struct devlink_rate *parent,
15101510
void *priv_child, void *priv_parent,
15111511
struct netlink_ext_ack *extack);
1512+
/**
1513+
* selftests_check() - queries if selftest is supported
1514+
* @devlink: devlink instance
1515+
* @id: test index
1516+
* @extack: extack for reporting error messages
1517+
*
1518+
* Return: true if test is supported by the driver
1519+
*/
1520+
bool (*selftest_check)(struct devlink *devlink, unsigned int id,
1521+
struct netlink_ext_ack *extack);
1522+
/**
1523+
* selftest_run() - Runs a selftest
1524+
* @devlink: devlink instance
1525+
* @id: test index
1526+
* @extack: extack for reporting error messages
1527+
*
1528+
* Return: status of the test
1529+
*/
1530+
enum devlink_selftest_status
1531+
(*selftest_run)(struct devlink *devlink, unsigned int id,
1532+
struct netlink_ext_ack *extack);
15121533
};
15131534

15141535
void *devlink_priv(struct devlink *devlink);

include/uapi/linux/devlink.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ enum devlink_command {
136136
DEVLINK_CMD_LINECARD_NEW,
137137
DEVLINK_CMD_LINECARD_DEL,
138138

139+
DEVLINK_CMD_SELFTESTS_GET, /* can dump */
140+
DEVLINK_CMD_SELFTESTS_RUN,
141+
139142
/* add new commands above here */
140143
__DEVLINK_CMD_MAX,
141144
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -276,6 +279,30 @@ enum {
276279
#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
277280
(_BITUL(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
278281

282+
enum devlink_attr_selftest_id {
283+
DEVLINK_ATTR_SELFTEST_ID_UNSPEC,
284+
DEVLINK_ATTR_SELFTEST_ID_FLASH, /* flag */
285+
286+
__DEVLINK_ATTR_SELFTEST_ID_MAX,
287+
DEVLINK_ATTR_SELFTEST_ID_MAX = __DEVLINK_ATTR_SELFTEST_ID_MAX - 1
288+
};
289+
290+
enum devlink_selftest_status {
291+
DEVLINK_SELFTEST_STATUS_SKIP,
292+
DEVLINK_SELFTEST_STATUS_PASS,
293+
DEVLINK_SELFTEST_STATUS_FAIL
294+
};
295+
296+
enum devlink_attr_selftest_result {
297+
DEVLINK_ATTR_SELFTEST_RESULT_UNSPEC,
298+
DEVLINK_ATTR_SELFTEST_RESULT, /* nested */
299+
DEVLINK_ATTR_SELFTEST_RESULT_ID, /* u32, enum devlink_attr_selftest_id */
300+
DEVLINK_ATTR_SELFTEST_RESULT_STATUS, /* u8, enum devlink_selftest_status */
301+
302+
__DEVLINK_ATTR_SELFTEST_RESULT_MAX,
303+
DEVLINK_ATTR_SELFTEST_RESULT_MAX = __DEVLINK_ATTR_SELFTEST_RESULT_MAX - 1
304+
};
305+
279306
/**
280307
* enum devlink_trap_action - Packet trap action.
281308
* @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
@@ -578,6 +605,8 @@ enum devlink_attr {
578605

579606
DEVLINK_ATTR_NESTED_DEVLINK, /* nested */
580607

608+
DEVLINK_ATTR_SELFTESTS, /* nested */
609+
581610
/* add new attributes above here, update the policy in devlink.c */
582611

583612
__DEVLINK_ATTR_MAX,

0 commit comments

Comments
 (0)