@@ -154,18 +154,32 @@ static void mt76x02_process_tx_status_fifo(struct mt76x02_dev *dev)
154
154
static void mt76x02_tx_tasklet (unsigned long data )
155
155
{
156
156
struct mt76x02_dev * dev = (struct mt76x02_dev * )data ;
157
- int i ;
158
157
158
+ mt76x02_mac_poll_tx_status (dev , false);
159
159
mt76x02_process_tx_status_fifo (dev );
160
160
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
+
161
171
for (i = MT_TXQ_MCU ; i >= 0 ; i -- )
162
172
mt76_queue_tx_cleanup (dev , i , false);
163
173
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 );
165
176
166
- mt76_txq_schedule_all (& dev -> mt76 );
177
+ for (i = MT_TXQ_MCU ; i >= 0 ; i -- )
178
+ mt76_queue_tx_cleanup (dev , i , false);
167
179
168
- mt76x02_irq_enable (dev , MT_INT_TX_DONE_ALL );
180
+ tasklet_schedule (& dev -> mt76 .tx_tasklet );
181
+
182
+ return 0 ;
169
183
}
170
184
171
185
int mt76x02_dma_init (struct mt76x02_dev * dev )
@@ -223,7 +237,15 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
223
237
if (ret )
224
238
return ret ;
225
239
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 ;
227
249
}
228
250
EXPORT_SYMBOL_GPL (mt76x02_dma_init );
229
251
@@ -251,11 +273,6 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
251
273
252
274
intr &= dev -> mt76 .mmio .irqmask ;
253
275
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
-
259
276
if (intr & MT_INT_RX_DONE (0 )) {
260
277
mt76x02_irq_disable (dev , MT_INT_RX_DONE (0 ));
261
278
napi_schedule (& dev -> mt76 .napi [0 ]);
@@ -277,9 +294,12 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
277
294
mt76_queue_kick (dev , dev -> mt76 .q_tx [MT_TXQ_PSD ].q );
278
295
}
279
296
280
- if (intr & MT_INT_TX_STAT ) {
297
+ if (intr & MT_INT_TX_STAT )
281
298
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 );
283
303
}
284
304
285
305
if (intr & MT_INT_GPTIMER ) {
@@ -310,6 +330,7 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)
310
330
void mt76x02_dma_cleanup (struct mt76x02_dev * dev )
311
331
{
312
332
tasklet_kill (& dev -> mt76 .tx_tasklet );
333
+ netif_napi_del (& dev -> tx_napi );
313
334
mt76_dma_cleanup (& dev -> mt76 );
314
335
}
315
336
EXPORT_SYMBOL_GPL (mt76x02_dma_cleanup );
@@ -429,6 +450,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
429
450
430
451
tasklet_disable (& dev -> pre_tbtt_tasklet );
431
452
tasklet_disable (& dev -> mt76 .tx_tasklet );
453
+ napi_disable (& dev -> tx_napi );
432
454
433
455
for (i = 0 ; i < ARRAY_SIZE (dev -> mt76 .napi ); i ++ )
434
456
napi_disable (& dev -> mt76 .napi [i ]);
@@ -482,7 +504,8 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
482
504
clear_bit (MT76_RESET , & dev -> mt76 .state );
483
505
484
506
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 );
486
509
487
510
tasklet_enable (& dev -> pre_tbtt_tasklet );
488
511
0 commit comments