@@ -627,7 +627,7 @@ static void mt76u_complete_rx(struct urb *urb)
627627
628628 q -> head = (q -> head + 1 ) % q -> ndesc ;
629629 q -> queued ++ ;
630- tasklet_schedule (& dev -> usb .rx_tasklet );
630+ mt76_worker_schedule (& dev -> usb .rx_worker );
631631out :
632632 spin_unlock_irqrestore (& q -> lock , flags );
633633}
@@ -665,13 +665,17 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
665665 }
666666 mt76u_submit_rx_buf (dev , qid , urb );
667667 }
668- if (qid == MT_RXQ_MAIN )
668+ if (qid == MT_RXQ_MAIN ) {
669+ local_bh_disable ();
669670 mt76_rx_poll_complete (dev , MT_RXQ_MAIN , NULL );
671+ local_bh_enable ();
672+ }
670673}
671674
672- static void mt76u_rx_tasklet (struct tasklet_struct * t )
675+ static void mt76u_rx_worker (struct mt76_worker * w )
673676{
674- struct mt76_dev * dev = from_tasklet (dev , t , usb .rx_tasklet );
677+ struct mt76_usb * usb = container_of (w , struct mt76_usb , rx_worker );
678+ struct mt76_dev * dev = container_of (usb , struct mt76_dev , usb );
675679 int i ;
676680
677681 rcu_read_lock ();
@@ -737,8 +741,13 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
737741 struct page * page ;
738742 int i ;
739743
740- for (i = 0 ; i < q -> ndesc ; i ++ )
744+ for (i = 0 ; i < q -> ndesc ; i ++ ) {
745+ if (!q -> entry [i ].urb )
746+ continue ;
747+
741748 mt76u_urb_free (q -> entry [i ].urb );
749+ q -> entry [i ].urb = NULL ;
750+ }
742751
743752 if (!q -> rx_page .va )
744753 return ;
@@ -752,6 +761,8 @@ static void mt76u_free_rx(struct mt76_dev *dev)
752761{
753762 int i ;
754763
764+ mt76_worker_teardown (& dev -> usb .rx_worker );
765+
755766 mt76_for_each_q_rx (dev , i )
756767 mt76u_free_rx_queue (dev , & dev -> q_rx [i ]);
757768}
@@ -760,15 +771,15 @@ void mt76u_stop_rx(struct mt76_dev *dev)
760771{
761772 int i ;
762773
774+ mt76_worker_disable (& dev -> usb .rx_worker );
775+
763776 mt76_for_each_q_rx (dev , i ) {
764777 struct mt76_queue * q = & dev -> q_rx [i ];
765778 int j ;
766779
767780 for (j = 0 ; j < q -> ndesc ; j ++ )
768781 usb_poison_urb (q -> entry [j ].urb );
769782 }
770-
771- tasklet_kill (& dev -> usb .rx_tasklet );
772783}
773784EXPORT_SYMBOL_GPL (mt76u_stop_rx );
774785
@@ -788,6 +799,8 @@ int mt76u_resume_rx(struct mt76_dev *dev)
788799 return err ;
789800 }
790801
802+ mt76_worker_enable (& dev -> usb .rx_worker );
803+
791804 return 0 ;
792805}
793806EXPORT_SYMBOL_GPL (mt76u_resume_rx );
@@ -1011,8 +1024,10 @@ static void mt76u_free_tx(struct mt76_dev *dev)
10111024 if (!q )
10121025 continue ;
10131026
1014- for (j = 0 ; j < q -> ndesc ; j ++ )
1027+ for (j = 0 ; j < q -> ndesc ; j ++ ) {
10151028 usb_free_urb (q -> entry [j ].urb );
1029+ q -> entry [j ].urb = NULL ;
1030+ }
10161031 }
10171032}
10181033
@@ -1102,15 +1117,14 @@ int mt76u_init(struct mt76_dev *dev,
11021117 };
11031118 struct usb_device * udev = interface_to_usbdev (intf );
11041119 struct mt76_usb * usb = & dev -> usb ;
1105- int err = - ENOMEM ;
1120+ int err ;
11061121
11071122 mt76u_ops .rr = ext ? mt76u_rr_ext : mt76u_rr ;
11081123 mt76u_ops .wr = ext ? mt76u_wr_ext : mt76u_wr ;
11091124 mt76u_ops .rmw = ext ? mt76u_rmw_ext : mt76u_rmw ;
11101125 mt76u_ops .write_copy = ext ? mt76u_copy_ext : mt76u_copy ;
11111126
11121127 dev -> tx_worker .fn = mt76u_tx_worker ;
1113- tasklet_setup (& usb -> rx_tasklet , mt76u_rx_tasklet );
11141128 INIT_WORK (& usb -> stat_work , mt76u_tx_status_data );
11151129
11161130 usb -> data_len = usb_maxpacket (udev , usb_sndctrlpipe (udev , 0 ), 1 );
@@ -1119,7 +1133,7 @@ int mt76u_init(struct mt76_dev *dev,
11191133
11201134 usb -> data = devm_kmalloc (dev -> dev , usb -> data_len , GFP_KERNEL );
11211135 if (!usb -> data )
1122- goto error ;
1136+ return - ENOMEM ;
11231137
11241138 mutex_init (& usb -> usb_ctrl_mtx );
11251139 dev -> bus = & mt76u_ops ;
@@ -1131,14 +1145,16 @@ int mt76u_init(struct mt76_dev *dev,
11311145
11321146 err = mt76u_set_endpoints (intf , usb );
11331147 if (err < 0 )
1134- goto error ;
1148+ return err ;
11351149
1136- return 0 ;
1150+ err = mt76_worker_setup (dev -> hw , & usb -> rx_worker , mt76u_rx_worker ,
1151+ "usb-rx" );
1152+ if (err )
1153+ return err ;
11371154
1138- error :
1139- destroy_workqueue (dev -> wq );
1155+ sched_set_fifo_low (usb -> rx_worker .task );
11401156
1141- return err ;
1157+ return 0 ;
11421158}
11431159EXPORT_SYMBOL_GPL (mt76u_init );
11441160
0 commit comments