@@ -154,18 +154,32 @@ static void mt76x02_process_tx_status_fifo(struct mt76x02_dev *dev)
154154static void mt76x02_tx_tasklet (unsigned long data )
155155{
156156 struct mt76x02_dev * dev = (struct mt76x02_dev * )data ;
157- int i ;
158157
158+ mt76x02_mac_poll_tx_status (dev , false);
159159 mt76x02_process_tx_status_fifo (dev );
160160
161+ mt76_txq_schedule_all (& dev -> mt76 );
162+ }
163+
164+ int mt76x02_poll_tx (struct napi_struct * napi , int budget )
165+ {
166+ struct mt76x02_dev * dev = container_of (napi , struct mt76x02_dev , tx_napi );
167+ int i ;
168+
169+ mt76x02_mac_poll_tx_status (dev , false);
170+
161171 for (i = MT_TXQ_MCU ; i >= 0 ; i -- )
162172 mt76_queue_tx_cleanup (dev , i , false);
163173
164- mt76x02_mac_poll_tx_status (dev , false);
174+ if (napi_complete_done (napi , 0 ))
175+ mt76x02_irq_enable (dev , MT_INT_TX_DONE_ALL );
165176
166- mt76_txq_schedule_all (& dev -> mt76 );
177+ for (i = MT_TXQ_MCU ; i >= 0 ; i -- )
178+ mt76_queue_tx_cleanup (dev , i , false);
167179
168- mt76x02_irq_enable (dev , MT_INT_TX_DONE_ALL );
180+ tasklet_schedule (& dev -> mt76 .tx_tasklet );
181+
182+ return 0 ;
169183}
170184
171185int mt76x02_dma_init (struct mt76x02_dev * dev )
@@ -223,7 +237,15 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
223237 if (ret )
224238 return ret ;
225239
226- return mt76_init_queues (dev );
240+ ret = mt76_init_queues (dev );
241+ if (ret )
242+ return ret ;
243+
244+ netif_tx_napi_add (& dev -> mt76 .napi_dev , & dev -> tx_napi , mt76x02_poll_tx ,
245+ NAPI_POLL_WEIGHT );
246+ napi_enable (& dev -> tx_napi );
247+
248+ return 0 ;
227249}
228250EXPORT_SYMBOL_GPL (mt76x02_dma_init );
229251
@@ -251,11 +273,6 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
251273
252274 intr &= dev -> mt76 .mmio .irqmask ;
253275
254- if (intr & MT_INT_TX_DONE_ALL ) {
255- mt76x02_irq_disable (dev , MT_INT_TX_DONE_ALL );
256- tasklet_schedule (& dev -> mt76 .tx_tasklet );
257- }
258-
259276 if (intr & MT_INT_RX_DONE (0 )) {
260277 mt76x02_irq_disable (dev , MT_INT_RX_DONE (0 ));
261278 napi_schedule (& dev -> mt76 .napi [0 ]);
@@ -277,9 +294,12 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
277294 mt76_queue_kick (dev , dev -> mt76 .q_tx [MT_TXQ_PSD ].q );
278295 }
279296
280- if (intr & MT_INT_TX_STAT ) {
297+ if (intr & MT_INT_TX_STAT )
281298 mt76x02_mac_poll_tx_status (dev , true);
282- tasklet_schedule (& dev -> mt76 .tx_tasklet );
299+
300+ if (intr & (MT_INT_TX_STAT | MT_INT_TX_DONE_ALL )) {
301+ mt76x02_irq_disable (dev , MT_INT_TX_DONE_ALL );
302+ napi_schedule (& dev -> tx_napi );
283303 }
284304
285305 if (intr & MT_INT_GPTIMER ) {
@@ -310,6 +330,7 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)
310330void mt76x02_dma_cleanup (struct mt76x02_dev * dev )
311331{
312332 tasklet_kill (& dev -> mt76 .tx_tasklet );
333+ netif_napi_del (& dev -> tx_napi );
313334 mt76_dma_cleanup (& dev -> mt76 );
314335}
315336EXPORT_SYMBOL_GPL (mt76x02_dma_cleanup );
@@ -429,6 +450,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
429450
430451 tasklet_disable (& dev -> pre_tbtt_tasklet );
431452 tasklet_disable (& dev -> mt76 .tx_tasklet );
453+ napi_disable (& dev -> tx_napi );
432454
433455 for (i = 0 ; i < ARRAY_SIZE (dev -> mt76 .napi ); i ++ )
434456 napi_disable (& dev -> mt76 .napi [i ]);
@@ -482,7 +504,8 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
482504 clear_bit (MT76_RESET , & dev -> mt76 .state );
483505
484506 tasklet_enable (& dev -> mt76 .tx_tasklet );
485- tasklet_schedule (& dev -> mt76 .tx_tasklet );
507+ napi_enable (& dev -> tx_napi );
508+ napi_schedule (& dev -> tx_napi );
486509
487510 tasklet_enable (& dev -> pre_tbtt_tasklet );
488511
0 commit comments