@@ -234,7 +234,7 @@ static void nicvf_handle_mbx_intr(struct nicvf *nic)
234
234
nic -> duplex == DUPLEX_FULL ?
235
235
"Full duplex" : "Half duplex" );
236
236
netif_carrier_on (nic -> netdev );
237
- netif_tx_wake_all_queues (nic -> netdev );
237
+ netif_tx_start_all_queues (nic -> netdev );
238
238
} else {
239
239
netdev_info (nic -> netdev , "%s: Link is Down\n" ,
240
240
nic -> netdev -> name );
@@ -425,6 +425,7 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev,
425
425
if (skb ) {
426
426
prefetch (skb );
427
427
dev_consume_skb_any (skb );
428
+ sq -> skbuff [cqe_tx -> sqe_ptr ] = (u64 )NULL ;
428
429
}
429
430
}
430
431
@@ -476,12 +477,13 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
476
477
static int nicvf_cq_intr_handler (struct net_device * netdev , u8 cq_idx ,
477
478
struct napi_struct * napi , int budget )
478
479
{
479
- int processed_cqe , work_done = 0 ;
480
+ int processed_cqe , work_done = 0 , tx_done = 0 ;
480
481
int cqe_count , cqe_head ;
481
482
struct nicvf * nic = netdev_priv (netdev );
482
483
struct queue_set * qs = nic -> qs ;
483
484
struct cmp_queue * cq = & qs -> cq [cq_idx ];
484
485
struct cqe_rx_t * cq_desc ;
486
+ struct netdev_queue * txq ;
485
487
486
488
spin_lock_bh (& cq -> lock );
487
489
loop :
@@ -496,8 +498,8 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
496
498
cqe_head = nicvf_queue_reg_read (nic , NIC_QSET_CQ_0_7_HEAD , cq_idx ) >> 9 ;
497
499
cqe_head &= 0xFFFF ;
498
500
499
- netdev_dbg (nic -> netdev , "%s cqe_count %d cqe_head %d\n" ,
500
- __func__ , cqe_count , cqe_head );
501
+ netdev_dbg (nic -> netdev , "%s CQ%d cqe_count %d cqe_head %d\n" ,
502
+ __func__ , cq_idx , cqe_count , cqe_head );
501
503
while (processed_cqe < cqe_count ) {
502
504
/* Get the CQ descriptor */
503
505
cq_desc = (struct cqe_rx_t * )GET_CQ_DESC (cq , cqe_head );
@@ -511,8 +513,8 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
511
513
break ;
512
514
}
513
515
514
- netdev_dbg (nic -> netdev , "cq_desc->cqe_type %d\n" ,
515
- cq_desc -> cqe_type );
516
+ netdev_dbg (nic -> netdev , "CQ%d cq_desc->cqe_type %d\n" ,
517
+ cq_idx , cq_desc -> cqe_type );
516
518
switch (cq_desc -> cqe_type ) {
517
519
case CQE_TYPE_RX :
518
520
nicvf_rcv_pkt_handler (netdev , napi , cq ,
@@ -522,6 +524,7 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
522
524
case CQE_TYPE_SEND :
523
525
nicvf_snd_pkt_handler (netdev , cq ,
524
526
(void * )cq_desc , CQE_TYPE_SEND );
527
+ tx_done ++ ;
525
528
break ;
526
529
case CQE_TYPE_INVALID :
527
530
case CQE_TYPE_RX_SPLIT :
@@ -532,8 +535,9 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
532
535
}
533
536
processed_cqe ++ ;
534
537
}
535
- netdev_dbg (nic -> netdev , "%s processed_cqe %d work_done %d budget %d\n" ,
536
- __func__ , processed_cqe , work_done , budget );
538
+ netdev_dbg (nic -> netdev ,
539
+ "%s CQ%d processed_cqe %d work_done %d budget %d\n" ,
540
+ __func__ , cq_idx , processed_cqe , work_done , budget );
537
541
538
542
/* Ring doorbell to inform H/W to reuse processed CQEs */
539
543
nicvf_queue_reg_write (nic , NIC_QSET_CQ_0_7_DOOR ,
@@ -543,6 +547,19 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
543
547
goto loop ;
544
548
545
549
done :
550
+ /* Wakeup TXQ if its stopped earlier due to SQ full */
551
+ if (tx_done ) {
552
+ txq = netdev_get_tx_queue (netdev , cq_idx );
553
+ if (netif_tx_queue_stopped (txq )) {
554
+ netif_tx_start_queue (txq );
555
+ nic -> drv_stats .txq_wake ++ ;
556
+ if (netif_msg_tx_err (nic ))
557
+ netdev_warn (netdev ,
558
+ "%s: Transmit queue wakeup SQ%d\n" ,
559
+ netdev -> name , cq_idx );
560
+ }
561
+ }
562
+
546
563
spin_unlock_bh (& cq -> lock );
547
564
return work_done ;
548
565
}
@@ -554,15 +571,10 @@ static int nicvf_poll(struct napi_struct *napi, int budget)
554
571
struct net_device * netdev = napi -> dev ;
555
572
struct nicvf * nic = netdev_priv (netdev );
556
573
struct nicvf_cq_poll * cq ;
557
- struct netdev_queue * txq ;
558
574
559
575
cq = container_of (napi , struct nicvf_cq_poll , napi );
560
576
work_done = nicvf_cq_intr_handler (netdev , cq -> cq_idx , napi , budget );
561
577
562
- txq = netdev_get_tx_queue (netdev , cq -> cq_idx );
563
- if (netif_tx_queue_stopped (txq ))
564
- netif_tx_wake_queue (txq );
565
-
566
578
if (work_done < budget ) {
567
579
/* Slow packet rate, exit polling */
568
580
napi_complete (napi );
@@ -833,9 +845,9 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
833
845
return NETDEV_TX_OK ;
834
846
}
835
847
836
- if (!nicvf_sq_append_skb ( nic , skb ) && !netif_tx_queue_stopped ( txq )) {
848
+ if (!netif_tx_queue_stopped ( txq ) && !nicvf_sq_append_skb ( nic , skb )) {
837
849
netif_tx_stop_queue (txq );
838
- nic -> drv_stats .tx_busy ++ ;
850
+ nic -> drv_stats .txq_stop ++ ;
839
851
if (netif_msg_tx_err (nic ))
840
852
netdev_warn (netdev ,
841
853
"%s: Transmit ring full, stopping SQ%d\n" ,
@@ -859,7 +871,6 @@ int nicvf_stop(struct net_device *netdev)
859
871
nicvf_send_msg_to_pf (nic , & mbx );
860
872
861
873
netif_carrier_off (netdev );
862
- netif_tx_disable (netdev );
863
874
864
875
/* Disable RBDR & QS error interrupts */
865
876
for (qidx = 0 ; qidx < qs -> rbdr_cnt ; qidx ++ ) {
@@ -894,6 +905,8 @@ int nicvf_stop(struct net_device *netdev)
894
905
kfree (cq_poll );
895
906
}
896
907
908
+ netif_tx_disable (netdev );
909
+
897
910
/* Free resources */
898
911
nicvf_config_data_transfer (nic , false);
899
912
@@ -988,6 +1001,9 @@ int nicvf_open(struct net_device *netdev)
988
1001
for (qidx = 0 ; qidx < qs -> rbdr_cnt ; qidx ++ )
989
1002
nicvf_enable_intr (nic , NICVF_INTR_RBDR , qidx );
990
1003
1004
+ nic -> drv_stats .txq_stop = 0 ;
1005
+ nic -> drv_stats .txq_wake = 0 ;
1006
+
991
1007
netif_carrier_on (netdev );
992
1008
netif_tx_start_all_queues (netdev );
993
1009
@@ -1278,6 +1294,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1278
1294
netdev -> hw_features = netdev -> features ;
1279
1295
1280
1296
netdev -> netdev_ops = & nicvf_netdev_ops ;
1297
+ netdev -> watchdog_timeo = NICVF_TX_TIMEOUT ;
1281
1298
1282
1299
INIT_WORK (& nic -> reset_task , nicvf_reset_task );
1283
1300
@@ -1318,11 +1335,17 @@ static void nicvf_remove(struct pci_dev *pdev)
1318
1335
pci_disable_device (pdev );
1319
1336
}
1320
1337
1338
+ static void nicvf_shutdown (struct pci_dev * pdev )
1339
+ {
1340
+ nicvf_remove (pdev );
1341
+ }
1342
+
1321
1343
static struct pci_driver nicvf_driver = {
1322
1344
.name = DRV_NAME ,
1323
1345
.id_table = nicvf_id_table ,
1324
1346
.probe = nicvf_probe ,
1325
1347
.remove = nicvf_remove ,
1348
+ .shutdown = nicvf_shutdown ,
1326
1349
};
1327
1350
1328
1351
static int __init nicvf_init_module (void )
0 commit comments