@@ -258,6 +258,7 @@ static int hns3_nic_net_up(struct net_device *netdev)
258
258
259
259
static int hns3_nic_net_open (struct net_device * netdev )
260
260
{
261
+ struct hns3_nic_priv * priv = netdev_priv (netdev );
261
262
int ret ;
262
263
263
264
netif_carrier_off (netdev );
@@ -273,6 +274,7 @@ static int hns3_nic_net_open(struct net_device *netdev)
273
274
return ret ;
274
275
}
275
276
277
+ priv -> last_reset_time = jiffies ;
276
278
return 0 ;
277
279
}
278
280
@@ -1322,10 +1324,91 @@ static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
1322
1324
return ret ;
1323
1325
}
1324
1326
1327
+ static bool hns3_get_tx_timeo_queue_info (struct net_device * ndev )
1328
+ {
1329
+ struct hns3_nic_priv * priv = netdev_priv (ndev );
1330
+ struct hns3_enet_ring * tx_ring = NULL ;
1331
+ int timeout_queue = 0 ;
1332
+ int hw_head , hw_tail ;
1333
+ int i ;
1334
+
1335
+ /* Find the stopped queue the same way the stack does */
1336
+ for (i = 0 ; i < ndev -> real_num_tx_queues ; i ++ ) {
1337
+ struct netdev_queue * q ;
1338
+ unsigned long trans_start ;
1339
+
1340
+ q = netdev_get_tx_queue (ndev , i );
1341
+ trans_start = q -> trans_start ;
1342
+ if (netif_xmit_stopped (q ) &&
1343
+ time_after (jiffies ,
1344
+ (trans_start + ndev -> watchdog_timeo ))) {
1345
+ timeout_queue = i ;
1346
+ break ;
1347
+ }
1348
+ }
1349
+
1350
+ if (i == ndev -> num_tx_queues ) {
1351
+ netdev_info (ndev ,
1352
+ "no netdev TX timeout queue found, timeout count: %llu\n" ,
1353
+ priv -> tx_timeout_count );
1354
+ return false;
1355
+ }
1356
+
1357
+ tx_ring = priv -> ring_data [timeout_queue ].ring ;
1358
+
1359
+ hw_head = readl_relaxed (tx_ring -> tqp -> io_base +
1360
+ HNS3_RING_TX_RING_HEAD_REG );
1361
+ hw_tail = readl_relaxed (tx_ring -> tqp -> io_base +
1362
+ HNS3_RING_TX_RING_TAIL_REG );
1363
+ netdev_info (ndev ,
1364
+ "tx_timeout count: %llu, queue id: %d, SW_NTU: 0x%x, SW_NTC: 0x%x, HW_HEAD: 0x%x, HW_TAIL: 0x%x, INT: 0x%x\n" ,
1365
+ priv -> tx_timeout_count ,
1366
+ timeout_queue ,
1367
+ tx_ring -> next_to_use ,
1368
+ tx_ring -> next_to_clean ,
1369
+ hw_head ,
1370
+ hw_tail ,
1371
+ readl (tx_ring -> tqp_vector -> mask_addr ));
1372
+
1373
+ return true;
1374
+ }
1375
+
1376
+ static void hns3_nic_net_timeout (struct net_device * ndev )
1377
+ {
1378
+ struct hns3_nic_priv * priv = netdev_priv (ndev );
1379
+ unsigned long last_reset_time = priv -> last_reset_time ;
1380
+ struct hnae3_handle * h = priv -> ae_handle ;
1381
+
1382
+ if (!hns3_get_tx_timeo_queue_info (ndev ))
1383
+ return ;
1384
+
1385
+ priv -> tx_timeout_count ++ ;
1386
+
1387
+ /* This timeout is far away enough from last timeout,
1388
+ * if timeout again,set the reset type to PF reset
1389
+ */
1390
+ if (time_after (jiffies , (last_reset_time + 20 * HZ )))
1391
+ priv -> reset_level = HNAE3_FUNC_RESET ;
1392
+
1393
+ /* Don't do any new action before the next timeout */
1394
+ else if (time_before (jiffies , (last_reset_time + ndev -> watchdog_timeo )))
1395
+ return ;
1396
+
1397
+ priv -> last_reset_time = jiffies ;
1398
+
1399
+ if (h -> ae_algo -> ops -> reset_event )
1400
+ h -> ae_algo -> ops -> reset_event (h , priv -> reset_level );
1401
+
1402
+ priv -> reset_level ++ ;
1403
+ if (priv -> reset_level > HNAE3_GLOBAL_RESET )
1404
+ priv -> reset_level = HNAE3_GLOBAL_RESET ;
1405
+ }
1406
+
1325
1407
static const struct net_device_ops hns3_nic_netdev_ops = {
1326
1408
.ndo_open = hns3_nic_net_open ,
1327
1409
.ndo_stop = hns3_nic_net_stop ,
1328
1410
.ndo_start_xmit = hns3_nic_net_xmit ,
1411
+ .ndo_tx_timeout = hns3_nic_net_timeout ,
1329
1412
.ndo_set_mac_address = hns3_nic_net_set_mac_address ,
1330
1413
.ndo_change_mtu = hns3_nic_change_mtu ,
1331
1414
.ndo_set_features = hns3_nic_set_features ,
@@ -2763,6 +2846,9 @@ static int hns3_client_init(struct hnae3_handle *handle)
2763
2846
priv -> dev = & pdev -> dev ;
2764
2847
priv -> netdev = netdev ;
2765
2848
priv -> ae_handle = handle ;
2849
+ priv -> last_reset_time = jiffies ;
2850
+ priv -> reset_level = HNAE3_FUNC_RESET ;
2851
+ priv -> tx_timeout_count = 0 ;
2766
2852
2767
2853
handle -> kinfo .netdev = netdev ;
2768
2854
handle -> priv = (void * )priv ;
0 commit comments