forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
23 * Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
34 * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
....@@ -7,19 +8,6 @@
78 * Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
89 * Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com>
910 * <http://rt2x00.serialmonkey.com>
10
- *
11
- * This program is free software; you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License as published by
13
- * the Free Software Foundation; either version 2 of the License, or
14
- * (at your option) any later version.
15
- *
16
- * This program is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
2311 */
2412
2513 /* Module: rt2800mmio
....@@ -35,6 +23,37 @@
3523 #include "rt2800.h"
3624 #include "rt2800lib.h"
3725 #include "rt2800mmio.h"
26
+
27
+unsigned int rt2800mmio_get_dma_done(struct data_queue *queue)
28
+{
29
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
30
+ struct queue_entry *entry;
31
+ int idx, qid;
32
+
33
+ switch (queue->qid) {
34
+ case QID_AC_VO:
35
+ case QID_AC_VI:
36
+ case QID_AC_BE:
37
+ case QID_AC_BK:
38
+ qid = queue->qid;
39
+ idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(qid));
40
+ break;
41
+ case QID_MGMT:
42
+ idx = rt2x00mmio_register_read(rt2x00dev, TX_DTX_IDX(5));
43
+ break;
44
+ case QID_RX:
45
+ entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);
46
+ idx = entry->entry_idx;
47
+ break;
48
+ default:
49
+ WARN_ON_ONCE(1);
50
+ idx = 0;
51
+ break;
52
+ }
53
+
54
+ return idx;
55
+}
56
+EXPORT_SYMBOL_GPL(rt2800mmio_get_dma_done);
3857
3958 /*
4059 * TX descriptor initialization
....@@ -175,161 +194,6 @@
175194 rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
176195 }
177196
178
-static bool rt2800mmio_txdone_entry_check(struct queue_entry *entry, u32 status)
179
-{
180
- __le32 *txwi;
181
- u32 word;
182
- int wcid, tx_wcid;
183
-
184
- wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
185
-
186
- txwi = rt2800_drv_get_txwi(entry);
187
- word = rt2x00_desc_read(txwi, 1);
188
- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID);
189
-
190
- return (tx_wcid == wcid);
191
-}
192
-
193
-static bool rt2800mmio_txdone_find_entry(struct queue_entry *entry, void *data)
194
-{
195
- u32 status = *(u32 *)data;
196
-
197
- /*
198
- * rt2800pci hardware might reorder frames when exchanging traffic
199
- * with multiple BA enabled STAs.
200
- *
201
- * For example, a tx queue
202
- * [ STA1 | STA2 | STA1 | STA2 ]
203
- * can result in tx status reports
204
- * [ STA1 | STA1 | STA2 | STA2 ]
205
- * when the hw decides to aggregate the frames for STA1 into one AMPDU.
206
- *
207
- * To mitigate this effect, associate the tx status to the first frame
208
- * in the tx queue with a matching wcid.
209
- */
210
- if (rt2800mmio_txdone_entry_check(entry, status) &&
211
- !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
212
- /*
213
- * Got a matching frame, associate the tx status with
214
- * the frame
215
- */
216
- entry->status = status;
217
- set_bit(ENTRY_DATA_STATUS_SET, &entry->flags);
218
- return true;
219
- }
220
-
221
- /* Check the next frame */
222
- return false;
223
-}
224
-
225
-static bool rt2800mmio_txdone_match_first(struct queue_entry *entry, void *data)
226
-{
227
- u32 status = *(u32 *)data;
228
-
229
- /*
230
- * Find the first frame without tx status and assign this status to it
231
- * regardless if it matches or not.
232
- */
233
- if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
234
- /*
235
- * Got a matching frame, associate the tx status with
236
- * the frame
237
- */
238
- entry->status = status;
239
- set_bit(ENTRY_DATA_STATUS_SET, &entry->flags);
240
- return true;
241
- }
242
-
243
- /* Check the next frame */
244
- return false;
245
-}
246
-static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry,
247
- void *data)
248
-{
249
- if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
250
- rt2800_txdone_entry(entry, entry->status,
251
- rt2800mmio_get_txwi(entry), true);
252
- return false;
253
- }
254
-
255
- /* No more frames to release */
256
- return true;
257
-}
258
-
259
-static bool rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev)
260
-{
261
- struct data_queue *queue;
262
- u32 status;
263
- u8 qid;
264
- int max_tx_done = 16;
265
-
266
- while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
267
- qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
268
- if (unlikely(qid >= QID_RX)) {
269
- /*
270
- * Unknown queue, this shouldn't happen. Just drop
271
- * this tx status.
272
- */
273
- rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n",
274
- qid);
275
- break;
276
- }
277
-
278
- queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
279
- if (unlikely(queue == NULL)) {
280
- /*
281
- * The queue is NULL, this shouldn't happen. Stop
282
- * processing here and drop the tx status
283
- */
284
- rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n",
285
- qid);
286
- break;
287
- }
288
-
289
- if (unlikely(rt2x00queue_empty(queue))) {
290
- /*
291
- * The queue is empty. Stop processing here
292
- * and drop the tx status.
293
- */
294
- rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n",
295
- qid);
296
- break;
297
- }
298
-
299
- /*
300
- * Let's associate this tx status with the first
301
- * matching frame.
302
- */
303
- if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE,
304
- Q_INDEX, &status,
305
- rt2800mmio_txdone_find_entry)) {
306
- /*
307
- * We cannot match the tx status to any frame, so just
308
- * use the first one.
309
- */
310
- if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE,
311
- Q_INDEX, &status,
312
- rt2800mmio_txdone_match_first)) {
313
- rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n",
314
- qid);
315
- break;
316
- }
317
- }
318
-
319
- /*
320
- * Release all frames with a valid tx status.
321
- */
322
- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE,
323
- Q_INDEX, NULL,
324
- rt2800mmio_txdone_release_entries);
325
-
326
- if (--max_tx_done == 0)
327
- break;
328
- }
329
-
330
- return !max_tx_done;
331
-}
332
-
333197 static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev,
334198 struct rt2x00_field32 irq_field)
335199 {
....@@ -346,32 +210,19 @@
346210 spin_unlock_irq(&rt2x00dev->irqmask_lock);
347211 }
348212
349
-void rt2800mmio_txstatus_tasklet(unsigned long data)
213
+void rt2800mmio_pretbtt_tasklet(struct tasklet_struct *t)
350214 {
351
- struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
352
- if (rt2800mmio_txdone(rt2x00dev))
353
- tasklet_schedule(&rt2x00dev->txstatus_tasklet);
354
-
355
- /*
356
- * No need to enable the tx status interrupt here as we always
357
- * leave it enabled to minimize the possibility of a tx status
358
- * register overflow. See comment in interrupt handler.
359
- */
360
-}
361
-EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet);
362
-
363
-void rt2800mmio_pretbtt_tasklet(unsigned long data)
364
-{
365
- struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
215
+ struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,
216
+ pretbtt_tasklet);
366217 rt2x00lib_pretbtt(rt2x00dev);
367218 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
368219 rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT);
369220 }
370221 EXPORT_SYMBOL_GPL(rt2800mmio_pretbtt_tasklet);
371222
372
-void rt2800mmio_tbtt_tasklet(unsigned long data)
223
+void rt2800mmio_tbtt_tasklet(struct tasklet_struct *t)
373224 {
374
- struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
225
+ struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t, tbtt_tasklet);
375226 struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
376227 u32 reg;
377228
....@@ -404,9 +255,10 @@
404255 }
405256 EXPORT_SYMBOL_GPL(rt2800mmio_tbtt_tasklet);
406257
407
-void rt2800mmio_rxdone_tasklet(unsigned long data)
258
+void rt2800mmio_rxdone_tasklet(struct tasklet_struct *t)
408259 {
409
- struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
260
+ struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,
261
+ rxdone_tasklet);
410262 if (rt2x00mmio_rxdone(rt2x00dev))
411263 tasklet_schedule(&rt2x00dev->rxdone_tasklet);
412264 else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
....@@ -414,9 +266,10 @@
414266 }
415267 EXPORT_SYMBOL_GPL(rt2800mmio_rxdone_tasklet);
416268
417
-void rt2800mmio_autowake_tasklet(unsigned long data)
269
+void rt2800mmio_autowake_tasklet(struct tasklet_struct *t)
418270 {
419
- struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
271
+ struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,
272
+ autowake_tasklet);
420273 rt2800mmio_wakeup(rt2x00dev);
421274 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
422275 rt2800mmio_enable_interrupt(rt2x00dev,
....@@ -424,10 +277,10 @@
424277 }
425278 EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
426279
427
-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
280
+static void rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)
428281 {
429282 u32 status;
430
- int i;
283
+ unsigned long flags;
431284
432285 /*
433286 * The TX_FIFO_STATUS interrupt needs special care. We should
....@@ -440,28 +293,35 @@
440293 * because we can schedule the tasklet multiple times (when the
441294 * interrupt fires again during tx status processing).
442295 *
443
- * Furthermore we don't disable the TX_FIFO_STATUS
444
- * interrupt here but leave it enabled so that the TX_STA_FIFO
445
- * can also be read while the tx status tasklet gets executed.
446
- *
447
- * Since we have only one producer and one consumer we don't
448
- * need to lock the kfifo.
296
+ * We also read statuses from tx status timeout timer, use
297
+ * lock to prevent concurent writes to fifo.
449298 */
450
- for (i = 0; i < rt2x00dev->tx->limit; i++) {
451
- status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO);
452299
300
+ spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
301
+
302
+ while (!kfifo_is_full(&rt2x00dev->txstatus_fifo)) {
303
+ status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO);
453304 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
454305 break;
455306
456
- if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) {
457
- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n");
458
- break;
459
- }
307
+ kfifo_put(&rt2x00dev->txstatus_fifo, status);
460308 }
461309
462
- /* Schedule the tasklet for processing the tx status. */
463
- tasklet_schedule(&rt2x00dev->txstatus_tasklet);
310
+ spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
464311 }
312
+
313
+void rt2800mmio_txstatus_tasklet(struct tasklet_struct *t)
314
+{
315
+ struct rt2x00_dev *rt2x00dev = from_tasklet(rt2x00dev, t,
316
+ txstatus_tasklet);
317
+
318
+ rt2800_txdone(rt2x00dev, 16);
319
+
320
+ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
321
+ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
322
+
323
+}
324
+EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet);
465325
466326 irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance)
467327 {
....@@ -486,11 +346,10 @@
486346 mask = ~reg;
487347
488348 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
489
- rt2800mmio_txstatus_interrupt(rt2x00dev);
490
- /*
491
- * Never disable the TX_FIFO_STATUS interrupt.
492
- */
493349 rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1);
350
+ rt2800mmio_fetch_txstatus(rt2x00dev);
351
+ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
352
+ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
494353 }
495354
496355 if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
....@@ -590,6 +449,9 @@
590449 }
591450 EXPORT_SYMBOL_GPL(rt2800mmio_start_queue);
592451
452
+/* 200 ms */
453
+#define TXSTATUS_TIMEOUT 200000000
454
+
593455 void rt2800mmio_kick_queue(struct data_queue *queue)
594456 {
595457 struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
....@@ -604,6 +466,8 @@
604466 entry = rt2x00queue_get_entry(queue, Q_INDEX);
605467 rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
606468 entry->entry_idx);
469
+ hrtimer_start(&rt2x00dev->txstatus_timer,
470
+ TXSTATUS_TIMEOUT, HRTIMER_MODE_REL);
607471 break;
608472 case QID_MGMT:
609473 entry = rt2x00queue_get_entry(queue, Q_INDEX);
....@@ -615,6 +479,50 @@
615479 }
616480 }
617481 EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue);
482
+
483
+void rt2800mmio_flush_queue(struct data_queue *queue, bool drop)
484
+{
485
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
486
+ bool tx_queue = false;
487
+ unsigned int i;
488
+
489
+ switch (queue->qid) {
490
+ case QID_AC_VO:
491
+ case QID_AC_VI:
492
+ case QID_AC_BE:
493
+ case QID_AC_BK:
494
+ tx_queue = true;
495
+ break;
496
+ case QID_RX:
497
+ break;
498
+ default:
499
+ return;
500
+ }
501
+
502
+ for (i = 0; i < 5; i++) {
503
+ /*
504
+ * Check if the driver is already done, otherwise we
505
+ * have to sleep a little while to give the driver/hw
506
+ * the oppurtunity to complete interrupt process itself.
507
+ */
508
+ if (rt2x00queue_empty(queue))
509
+ break;
510
+
511
+ /*
512
+ * For TX queues schedule completion tasklet to catch
513
+ * tx status timeouts, othewise just wait.
514
+ */
515
+ if (tx_queue)
516
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
517
+
518
+ /*
519
+ * Wait for a little while to give the driver
520
+ * the oppurtunity to recover itself.
521
+ */
522
+ msleep(50);
523
+ }
524
+}
525
+EXPORT_SYMBOL_GPL(rt2800mmio_flush_queue);
618526
619527 void rt2800mmio_stop_queue(struct data_queue *queue)
620528 {
....@@ -689,7 +597,6 @@
689597 break;
690598
691599 case QID_ATIM:
692
- /* fallthrough */
693600 default:
694601 BUG();
695602 break;
....@@ -743,6 +650,10 @@
743650 word = rt2x00_desc_read(entry_priv->desc, 1);
744651 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
745652 rt2x00_desc_write(entry_priv->desc, 1, word);
653
+
654
+ /* If last entry stop txstatus timer */
655
+ if (entry->queue->length == 1)
656
+ hrtimer_cancel(&rt2x00dev->txstatus_timer);
746657 }
747658 }
748659 EXPORT_SYMBOL_GPL(rt2800mmio_clear_entry);
....@@ -875,6 +786,70 @@
875786 }
876787 EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
877788
789
+static void rt2800mmio_work_txdone(struct work_struct *work)
790
+{
791
+ struct rt2x00_dev *rt2x00dev =
792
+ container_of(work, struct rt2x00_dev, txdone_work);
793
+
794
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
795
+ return;
796
+
797
+ while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
798
+ rt2800_txstatus_timeout(rt2x00dev)) {
799
+
800
+ tasklet_disable(&rt2x00dev->txstatus_tasklet);
801
+ rt2800_txdone(rt2x00dev, UINT_MAX);
802
+ rt2800_txdone_nostatus(rt2x00dev);
803
+ tasklet_enable(&rt2x00dev->txstatus_tasklet);
804
+ }
805
+
806
+ if (rt2800_txstatus_pending(rt2x00dev))
807
+ hrtimer_start(&rt2x00dev->txstatus_timer,
808
+ TXSTATUS_TIMEOUT, HRTIMER_MODE_REL);
809
+}
810
+
811
+static enum hrtimer_restart rt2800mmio_tx_sta_fifo_timeout(struct hrtimer *timer)
812
+{
813
+ struct rt2x00_dev *rt2x00dev =
814
+ container_of(timer, struct rt2x00_dev, txstatus_timer);
815
+
816
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
817
+ goto out;
818
+
819
+ if (!rt2800_txstatus_pending(rt2x00dev))
820
+ goto out;
821
+
822
+ rt2800mmio_fetch_txstatus(rt2x00dev);
823
+ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
824
+ tasklet_schedule(&rt2x00dev->txstatus_tasklet);
825
+ else
826
+ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
827
+out:
828
+ return HRTIMER_NORESTART;
829
+}
830
+
831
+int rt2800mmio_probe_hw(struct rt2x00_dev *rt2x00dev)
832
+{
833
+ int retval;
834
+
835
+ retval = rt2800_probe_hw(rt2x00dev);
836
+ if (retval)
837
+ return retval;
838
+
839
+ /*
840
+ * Set txstatus timer function.
841
+ */
842
+ rt2x00dev->txstatus_timer.function = rt2800mmio_tx_sta_fifo_timeout;
843
+
844
+ /*
845
+ * Overwrite TX done handler
846
+ */
847
+ INIT_WORK(&rt2x00dev->txdone_work, rt2800mmio_work_txdone);
848
+
849
+ return 0;
850
+}
851
+EXPORT_SYMBOL_GPL(rt2800mmio_probe_hw);
852
+
878853 MODULE_AUTHOR(DRV_PROJECT);
879854 MODULE_VERSION(DRV_VERSION);
880855 MODULE_DESCRIPTION("rt2800 MMIO library");