@@ -210,6 +210,10 @@ static int bnxt_get_sset_count(struct net_device *dev, int sset)
210
210
211
211
return num_stats ;
212
212
}
213
+ case ETH_SS_TEST :
214
+ if (!bp -> num_tests )
215
+ return - EOPNOTSUPP ;
216
+ return bp -> num_tests ;
213
217
default :
214
218
return - EOPNOTSUPP ;
215
219
}
@@ -307,6 +311,11 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
307
311
}
308
312
}
309
313
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 ;
310
319
default :
311
320
netdev_err (bp -> dev , "bnxt_get_strings invalid request %x\n" ,
312
321
stringset );
@@ -825,7 +834,7 @@ static void bnxt_get_drvinfo(struct net_device *dev,
825
834
sizeof (info -> fw_version ));
826
835
strlcpy (info -> bus_info , pci_name (bp -> pdev ), sizeof (info -> bus_info ));
827
836
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 ;
829
838
/* TODO CHIMP_FW: eeprom dump details */
830
839
info -> eedump_len = 0 ;
831
840
/* TODO CHIMP FW: reg dump details */
@@ -2168,6 +2177,130 @@ static int bnxt_set_phys_id(struct net_device *dev,
2168
2177
return rc ;
2169
2178
}
2170
2179
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
+
2171
2304
const struct ethtool_ops bnxt_ethtool_ops = {
2172
2305
.get_link_ksettings = bnxt_get_link_ksettings ,
2173
2306
.set_link_ksettings = bnxt_set_link_ksettings ,
@@ -2203,4 +2336,5 @@ const struct ethtool_ops bnxt_ethtool_ops = {
2203
2336
.get_module_eeprom = bnxt_get_module_eeprom ,
2204
2337
.nway_reset = bnxt_nway_reset ,
2205
2338
.set_phys_id = bnxt_set_phys_id ,
2339
+ .self_test = bnxt_self_test ,
2206
2340
};
0 commit comments