Skip to content

Commit eb51365

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Add basic ethtool -t selftest support.
Add the basic infrastructure and only firmware tests initially. Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f65a204 commit eb51365

File tree

4 files changed

+150
-3
lines changed

4 files changed

+150
-3
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7281,6 +7281,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
72817281
bnxt_clear_int_mode(bp);
72827282
bnxt_hwrm_func_drv_unrgtr(bp);
72837283
bnxt_free_hwrm_resources(bp);
7284+
bnxt_ethtool_free(bp);
72847285
bnxt_dcb_free(bp);
72857286
kfree(bp->edev);
72867287
bp->edev = NULL;
@@ -7603,6 +7604,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
76037604

76047605
bnxt_hwrm_func_qcfg(bp);
76057606
bnxt_hwrm_port_led_qcaps(bp);
7607+
bnxt_ethtool_init(bp);
76067608

76077609
bnxt_set_rx_skb_mode(bp, false);
76087610
bnxt_set_tpa_flags(bp);

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,6 @@ struct rx_tpa_end_cmp_ext {
426426

427427
#define BNXT_MIN_PKT_SIZE 52
428428

429-
#define BNXT_NUM_TESTS(bp) 0
430-
431429
#define BNXT_DEFAULT_RX_RING_SIZE 511
432430
#define BNXT_DEFAULT_TX_RING_SIZE 511
433431

@@ -911,6 +909,14 @@ struct bnxt_led_info {
911909
__le16 led_color_caps;
912910
};
913911

912+
#define BNXT_MAX_TEST 8
913+
914+
struct bnxt_test_info {
915+
u8 offline_mask;
916+
u16 timeout;
917+
char string[BNXT_MAX_TEST][ETH_GSTRING_LEN];
918+
};
919+
914920
#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
915921
#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014
916922
#define BNXT_CAG_REG_BASE 0x300000
@@ -1181,6 +1187,9 @@ struct bnxt {
11811187
u32 lpi_tmr_lo;
11821188
u32 lpi_tmr_hi;
11831189

1190+
u8 num_tests;
1191+
struct bnxt_test_info *test_info;
1192+
11841193
u8 wol_filter_id;
11851194
u8 wol;
11861195

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

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ static int bnxt_get_sset_count(struct net_device *dev, int sset)
210210

211211
return num_stats;
212212
}
213+
case ETH_SS_TEST:
214+
if (!bp->num_tests)
215+
return -EOPNOTSUPP;
216+
return bp->num_tests;
213217
default:
214218
return -EOPNOTSUPP;
215219
}
@@ -307,6 +311,11 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
307311
}
308312
}
309313
break;
314+
case ETH_SS_TEST:
315+
if (bp->num_tests)
316+
memcpy(buf, bp->test_info->string,
317+
bp->num_tests * ETH_GSTRING_LEN);
318+
break;
310319
default:
311320
netdev_err(bp->dev, "bnxt_get_strings invalid request %x\n",
312321
stringset);
@@ -825,7 +834,7 @@ static void bnxt_get_drvinfo(struct net_device *dev,
825834
sizeof(info->fw_version));
826835
strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
827836
info->n_stats = BNXT_NUM_STATS * bp->cp_nr_rings;
828-
info->testinfo_len = BNXT_NUM_TESTS(bp);
837+
info->testinfo_len = bp->num_tests;
829838
/* TODO CHIMP_FW: eeprom dump details */
830839
info->eedump_len = 0;
831840
/* TODO CHIMP FW: reg dump details */
@@ -2168,6 +2177,130 @@ static int bnxt_set_phys_id(struct net_device *dev,
21682177
return rc;
21692178
}
21702179

2180+
static int bnxt_run_fw_tests(struct bnxt *bp, u8 test_mask, u8 *test_results)
2181+
{
2182+
struct hwrm_selftest_exec_output *resp = bp->hwrm_cmd_resp_addr;
2183+
struct hwrm_selftest_exec_input req = {0};
2184+
int rc;
2185+
2186+
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_SELFTEST_EXEC, -1, -1);
2187+
mutex_lock(&bp->hwrm_cmd_lock);
2188+
resp->test_success = 0;
2189+
req.flags = test_mask;
2190+
rc = _hwrm_send_message(bp, &req, sizeof(req), bp->test_info->timeout);
2191+
*test_results = resp->test_success;
2192+
mutex_unlock(&bp->hwrm_cmd_lock);
2193+
return rc;
2194+
}
2195+
2196+
#define BNXT_DRV_TESTS 0
2197+
2198+
static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
2199+
u64 *buf)
2200+
{
2201+
struct bnxt *bp = netdev_priv(dev);
2202+
bool offline = false;
2203+
u8 test_results = 0;
2204+
u8 test_mask = 0;
2205+
int rc, i;
2206+
2207+
if (!bp->num_tests || !BNXT_SINGLE_PF(bp))
2208+
return;
2209+
memset(buf, 0, sizeof(u64) * bp->num_tests);
2210+
if (!netif_running(dev)) {
2211+
etest->flags |= ETH_TEST_FL_FAILED;
2212+
return;
2213+
}
2214+
2215+
if (etest->flags & ETH_TEST_FL_OFFLINE) {
2216+
if (bp->pf.active_vfs) {
2217+
etest->flags |= ETH_TEST_FL_FAILED;
2218+
netdev_warn(dev, "Offline tests cannot be run with active VFs\n");
2219+
return;
2220+
}
2221+
offline = true;
2222+
}
2223+
2224+
for (i = 0; i < bp->num_tests - BNXT_DRV_TESTS; i++) {
2225+
u8 bit_val = 1 << i;
2226+
2227+
if (!(bp->test_info->offline_mask & bit_val))
2228+
test_mask |= bit_val;
2229+
else if (offline)
2230+
test_mask |= bit_val;
2231+
}
2232+
if (!offline) {
2233+
bnxt_run_fw_tests(bp, test_mask, &test_results);
2234+
} else {
2235+
rc = bnxt_close_nic(bp, false, false);
2236+
if (rc)
2237+
return;
2238+
bnxt_run_fw_tests(bp, test_mask, &test_results);
2239+
bnxt_open_nic(bp, false, true);
2240+
}
2241+
for (i = 0; i < bp->num_tests - BNXT_DRV_TESTS; i++) {
2242+
u8 bit_val = 1 << i;
2243+
2244+
if ((test_mask & bit_val) && !(test_results & bit_val)) {
2245+
buf[i] = 1;
2246+
etest->flags |= ETH_TEST_FL_FAILED;
2247+
}
2248+
}
2249+
}
2250+
2251+
void bnxt_ethtool_init(struct bnxt *bp)
2252+
{
2253+
struct hwrm_selftest_qlist_output *resp = bp->hwrm_cmd_resp_addr;
2254+
struct hwrm_selftest_qlist_input req = {0};
2255+
struct bnxt_test_info *test_info;
2256+
int i, rc;
2257+
2258+
if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp))
2259+
return;
2260+
2261+
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_SELFTEST_QLIST, -1, -1);
2262+
mutex_lock(&bp->hwrm_cmd_lock);
2263+
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
2264+
if (rc)
2265+
goto ethtool_init_exit;
2266+
2267+
test_info = kzalloc(sizeof(*bp->test_info), GFP_KERNEL);
2268+
if (!test_info)
2269+
goto ethtool_init_exit;
2270+
2271+
bp->test_info = test_info;
2272+
bp->num_tests = resp->num_tests + BNXT_DRV_TESTS;
2273+
if (bp->num_tests > BNXT_MAX_TEST)
2274+
bp->num_tests = BNXT_MAX_TEST;
2275+
2276+
test_info->offline_mask = resp->offline_tests;
2277+
test_info->timeout = le16_to_cpu(resp->test_timeout);
2278+
if (!test_info->timeout)
2279+
test_info->timeout = HWRM_CMD_TIMEOUT;
2280+
for (i = 0; i < bp->num_tests; i++) {
2281+
char *str = test_info->string[i];
2282+
char *fw_str = resp->test0_name + i * 32;
2283+
2284+
strlcpy(str, fw_str, ETH_GSTRING_LEN);
2285+
strncat(str, " test", ETH_GSTRING_LEN - strlen(str));
2286+
if (test_info->offline_mask & (1 << i))
2287+
strncat(str, " (offline)",
2288+
ETH_GSTRING_LEN - strlen(str));
2289+
else
2290+
strncat(str, " (online)",
2291+
ETH_GSTRING_LEN - strlen(str));
2292+
}
2293+
2294+
ethtool_init_exit:
2295+
mutex_unlock(&bp->hwrm_cmd_lock);
2296+
}
2297+
2298+
void bnxt_ethtool_free(struct bnxt *bp)
2299+
{
2300+
kfree(bp->test_info);
2301+
bp->test_info = NULL;
2302+
}
2303+
21712304
const struct ethtool_ops bnxt_ethtool_ops = {
21722305
.get_link_ksettings = bnxt_get_link_ksettings,
21732306
.set_link_ksettings = bnxt_set_link_ksettings,
@@ -2203,4 +2336,5 @@ const struct ethtool_ops bnxt_ethtool_ops = {
22032336
.get_module_eeprom = bnxt_get_module_eeprom,
22042337
.nway_reset = bnxt_nway_reset,
22052338
.set_phys_id = bnxt_set_phys_id,
2339+
.self_test = bnxt_self_test,
22062340
};

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,7 @@ extern const struct ethtool_ops bnxt_ethtool_ops;
3939
u32 _bnxt_fw_to_ethtool_adv_spds(u16, u8);
4040
u32 bnxt_fw_to_ethtool_speed(u16);
4141
u16 bnxt_get_fw_auto_link_speeds(u32);
42+
void bnxt_ethtool_init(struct bnxt *bp);
43+
void bnxt_ethtool_free(struct bnxt *bp);
4244

4345
#endif

0 commit comments

Comments
 (0)