@@ -540,7 +540,7 @@ static void mt76u_rx_tasklet(unsigned long data)
540540 rcu_read_unlock ();
541541}
542542
543- int mt76u_submit_rx_buffers (struct mt76_dev * dev )
543+ static int mt76u_submit_rx_buffers (struct mt76_dev * dev )
544544{
545545 struct mt76_queue * q = & dev -> q_rx [MT_RXQ_MAIN ];
546546 unsigned long flags ;
@@ -558,7 +558,6 @@ int mt76u_submit_rx_buffers(struct mt76_dev *dev)
558558
559559 return err ;
560560}
561- EXPORT_SYMBOL_GPL (mt76u_submit_rx_buffers );
562561
563562static int mt76u_alloc_rx (struct mt76_dev * dev )
564563{
@@ -605,14 +604,29 @@ static void mt76u_free_rx(struct mt76_dev *dev)
605604 memset (& q -> rx_page , 0 , sizeof (q -> rx_page ));
606605}
607606
608- static void mt76u_stop_rx (struct mt76_dev * dev )
607+ void mt76u_stop_rx (struct mt76_dev * dev )
609608{
610609 struct mt76_queue * q = & dev -> q_rx [MT_RXQ_MAIN ];
611610 int i ;
612611
613612 for (i = 0 ; i < q -> ndesc ; i ++ )
614- usb_kill_urb (q -> entry [i ].urb );
613+ usb_poison_urb (q -> entry [i ].urb );
614+
615+ tasklet_kill (& dev -> usb .rx_tasklet );
616+ }
617+ EXPORT_SYMBOL_GPL (mt76u_stop_rx );
618+
619+ int mt76u_resume_rx (struct mt76_dev * dev )
620+ {
621+ struct mt76_queue * q = & dev -> q_rx [MT_RXQ_MAIN ];
622+ int i ;
623+
624+ for (i = 0 ; i < q -> ndesc ; i ++ )
625+ usb_unpoison_urb (q -> entry [i ].urb );
626+
627+ return mt76u_submit_rx_buffers (dev );
615628}
629+ EXPORT_SYMBOL_GPL (mt76u_resume_rx );
616630
617631static void mt76u_tx_tasklet (unsigned long data )
618632{
@@ -834,38 +848,54 @@ static void mt76u_free_tx(struct mt76_dev *dev)
834848 }
835849}
836850
837- static void mt76u_stop_tx (struct mt76_dev * dev )
851+ void mt76u_stop_tx (struct mt76_dev * dev )
838852{
853+ struct mt76_queue_entry entry ;
839854 struct mt76_queue * q ;
840- int i , j ;
855+ int i , j , ret ;
841856
842- for (i = 0 ; i < IEEE80211_NUM_ACS ; i ++ ) {
843- q = dev -> q_tx [i ].q ;
844- for (j = 0 ; j < q -> ndesc ; j ++ )
845- usb_kill_urb (q -> entry [j ].urb );
846- }
847- }
857+ ret = wait_event_timeout (dev -> tx_wait , !mt76_has_tx_pending (dev ), HZ /5 );
858+ if (!ret ) {
859+ dev_err (dev -> dev , "timed out waiting for pending tx\n" );
848860
849- void mt76u_stop_queues (struct mt76_dev * dev )
850- {
851- tasklet_disable (& dev -> usb .rx_tasklet );
852- tasklet_disable (& dev -> tx_tasklet );
861+ for (i = 0 ; i < IEEE80211_NUM_ACS ; i ++ ) {
862+ q = dev -> q_tx [i ].q ;
863+ for (j = 0 ; j < q -> ndesc ; j ++ )
864+ usb_kill_urb (q -> entry [j ].urb );
865+ }
853866
854- mt76u_stop_rx (dev );
855- mt76u_stop_tx (dev );
856- }
857- EXPORT_SYMBOL_GPL (mt76u_stop_queues );
867+ tasklet_kill (& dev -> tx_tasklet );
868+
869+ /* On device removal we maight queue skb's, but mt76u_tx_kick()
870+ * will fail to submit urb, cleanup those skb's manually.
871+ */
872+ for (i = 0 ; i < IEEE80211_NUM_ACS ; i ++ ) {
873+ q = dev -> q_tx [i ].q ;
874+
875+ /* Assure we are in sync with killed tasklet. */
876+ spin_lock_bh (& q -> lock );
877+ while (q -> queued ) {
878+ entry = q -> entry [q -> head ];
879+ q -> head = (q -> head + 1 ) % q -> ndesc ;
880+ q -> queued -- ;
881+
882+ dev -> drv -> tx_complete_skb (dev , i , & entry );
883+ }
884+ spin_unlock_bh (& q -> lock );
885+ }
886+ }
858887
859- void mt76u_stop_stat_wk (struct mt76_dev * dev )
860- {
861888 cancel_delayed_work_sync (& dev -> usb .stat_work );
862889 clear_bit (MT76_READING_STATS , & dev -> state );
890+
891+ mt76_tx_status_check (dev , NULL , true);
863892}
864- EXPORT_SYMBOL_GPL (mt76u_stop_stat_wk );
893+ EXPORT_SYMBOL_GPL (mt76u_stop_tx );
865894
866895void mt76u_queues_deinit (struct mt76_dev * dev )
867896{
868- mt76u_stop_queues (dev );
897+ mt76u_stop_rx (dev );
898+ mt76u_stop_tx (dev );
869899
870900 mt76u_free_rx (dev );
871901 mt76u_free_tx (dev );
0 commit comments