.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | Copyright (C) 2010 Willow Garage <http://www.willowgarage.com> |
---|
3 | 4 | Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> |
---|
.. | .. |
---|
7 | 8 | Copyright (C) 2009 Axel Kollhofer <rain_maker@root-forum.org> |
---|
8 | 9 | <http://rt2x00.serialmonkey.com> |
---|
9 | 10 | |
---|
10 | | - This program is free software; you can redistribute it and/or modify |
---|
11 | | - it under the terms of the GNU General Public License as published by |
---|
12 | | - the Free Software Foundation; either version 2 of the License, or |
---|
13 | | - (at your option) any later version. |
---|
14 | | - |
---|
15 | | - This program is distributed in the hope that it will be useful, |
---|
16 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - GNU General Public License for more details. |
---|
19 | | - |
---|
20 | | - You should have received a copy of the GNU General Public License |
---|
21 | | - along with this program; if not, see <http://www.gnu.org/licenses/>. |
---|
22 | 11 | */ |
---|
23 | 12 | |
---|
24 | 13 | /* |
---|
.. | .. |
---|
100 | 89 | } |
---|
101 | 90 | } |
---|
102 | 91 | |
---|
103 | | -/* |
---|
104 | | - * test if there is an entry in any TX queue for which DMA is done |
---|
105 | | - * but the TX status has not been returned yet |
---|
106 | | - */ |
---|
107 | | -static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) |
---|
108 | | -{ |
---|
109 | | - struct data_queue *queue; |
---|
110 | | - |
---|
111 | | - tx_queue_for_each(rt2x00dev, queue) { |
---|
112 | | - if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) != |
---|
113 | | - rt2x00queue_get_entry(queue, Q_INDEX_DONE)) |
---|
114 | | - return true; |
---|
115 | | - } |
---|
116 | | - return false; |
---|
117 | | -} |
---|
118 | | - |
---|
119 | | -static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) |
---|
120 | | -{ |
---|
121 | | - bool tout; |
---|
122 | | - |
---|
123 | | - if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
---|
124 | | - return false; |
---|
125 | | - |
---|
126 | | - tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); |
---|
127 | | - if (unlikely(tout)) |
---|
128 | | - rt2x00_dbg(entry->queue->rt2x00dev, |
---|
129 | | - "TX status timeout for entry %d in queue %d\n", |
---|
130 | | - entry->entry_idx, entry->queue->qid); |
---|
131 | | - return tout; |
---|
132 | | - |
---|
133 | | -} |
---|
134 | | - |
---|
135 | | -static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) |
---|
136 | | -{ |
---|
137 | | - struct data_queue *queue; |
---|
138 | | - struct queue_entry *entry; |
---|
139 | | - |
---|
140 | | - tx_queue_for_each(rt2x00dev, queue) { |
---|
141 | | - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
---|
142 | | - if (rt2800usb_entry_txstatus_timeout(entry)) |
---|
143 | | - return true; |
---|
144 | | - } |
---|
145 | | - return false; |
---|
146 | | -} |
---|
147 | | - |
---|
148 | 92 | #define TXSTATUS_READ_INTERVAL 1000000 |
---|
149 | 93 | |
---|
150 | 94 | static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, |
---|
.. | .. |
---|
171 | 115 | } |
---|
172 | 116 | |
---|
173 | 117 | /* Check if there is any entry that timedout waiting on TX status */ |
---|
174 | | - if (rt2800usb_txstatus_timeout(rt2x00dev)) |
---|
| 118 | + if (rt2800_txstatus_timeout(rt2x00dev)) |
---|
175 | 119 | queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); |
---|
176 | 120 | |
---|
177 | | - if (rt2800usb_txstatus_pending(rt2x00dev)) { |
---|
| 121 | + if (rt2800_txstatus_pending(rt2x00dev)) { |
---|
178 | 122 | /* Read register after 1 ms */ |
---|
179 | 123 | hrtimer_start(&rt2x00dev->txstatus_timer, |
---|
180 | 124 | TXSTATUS_READ_INTERVAL, |
---|
.. | .. |
---|
189 | 133 | * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck |
---|
190 | 134 | * here again if status reading is needed. |
---|
191 | 135 | */ |
---|
192 | | - if (rt2800usb_txstatus_pending(rt2x00dev) && |
---|
| 136 | + if (rt2800_txstatus_pending(rt2x00dev) && |
---|
193 | 137 | !test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) |
---|
194 | 138 | return true; |
---|
195 | 139 | else |
---|
.. | .. |
---|
435 | 379 | return retval; |
---|
436 | 380 | } |
---|
437 | 381 | |
---|
| 382 | +static unsigned int rt2800usb_get_dma_done(struct data_queue *queue) |
---|
| 383 | +{ |
---|
| 384 | + struct queue_entry *entry; |
---|
| 385 | + |
---|
| 386 | + entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE); |
---|
| 387 | + return entry->entry_idx; |
---|
| 388 | +} |
---|
| 389 | + |
---|
438 | 390 | /* |
---|
439 | 391 | * TX descriptor initialization |
---|
440 | 392 | */ |
---|
.. | .. |
---|
501 | 453 | /* |
---|
502 | 454 | * TX control handlers |
---|
503 | 455 | */ |
---|
504 | | -static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) |
---|
505 | | -{ |
---|
506 | | - __le32 *txwi; |
---|
507 | | - u32 word; |
---|
508 | | - int wcid, ack, pid; |
---|
509 | | - int tx_wcid, tx_ack, tx_pid, is_agg; |
---|
510 | | - |
---|
511 | | - /* |
---|
512 | | - * This frames has returned with an IO error, |
---|
513 | | - * so the status report is not intended for this |
---|
514 | | - * frame. |
---|
515 | | - */ |
---|
516 | | - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) |
---|
517 | | - return false; |
---|
518 | | - |
---|
519 | | - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); |
---|
520 | | - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); |
---|
521 | | - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); |
---|
522 | | - is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); |
---|
523 | | - |
---|
524 | | - /* |
---|
525 | | - * Validate if this TX status report is intended for |
---|
526 | | - * this entry by comparing the WCID/ACK/PID fields. |
---|
527 | | - */ |
---|
528 | | - txwi = rt2800usb_get_txwi(entry); |
---|
529 | | - |
---|
530 | | - word = rt2x00_desc_read(txwi, 1); |
---|
531 | | - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); |
---|
532 | | - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); |
---|
533 | | - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); |
---|
534 | | - |
---|
535 | | - if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { |
---|
536 | | - rt2x00_dbg(entry->queue->rt2x00dev, |
---|
537 | | - "TX status report missed for queue %d entry %d\n", |
---|
538 | | - entry->queue->qid, entry->entry_idx); |
---|
539 | | - return false; |
---|
540 | | - } |
---|
541 | | - |
---|
542 | | - return true; |
---|
543 | | -} |
---|
544 | | - |
---|
545 | | -static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) |
---|
546 | | -{ |
---|
547 | | - struct data_queue *queue; |
---|
548 | | - struct queue_entry *entry; |
---|
549 | | - u32 reg; |
---|
550 | | - u8 qid; |
---|
551 | | - bool match; |
---|
552 | | - |
---|
553 | | - while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { |
---|
554 | | - /* |
---|
555 | | - * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is |
---|
556 | | - * guaranteed to be one of the TX QIDs . |
---|
557 | | - */ |
---|
558 | | - qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); |
---|
559 | | - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
---|
560 | | - |
---|
561 | | - if (unlikely(rt2x00queue_empty(queue))) { |
---|
562 | | - rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", |
---|
563 | | - qid); |
---|
564 | | - break; |
---|
565 | | - } |
---|
566 | | - |
---|
567 | | - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
---|
568 | | - |
---|
569 | | - if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
---|
570 | | - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { |
---|
571 | | - rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", |
---|
572 | | - entry->entry_idx, qid); |
---|
573 | | - break; |
---|
574 | | - } |
---|
575 | | - |
---|
576 | | - match = rt2800usb_txdone_entry_check(entry, reg); |
---|
577 | | - rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match); |
---|
578 | | - } |
---|
579 | | -} |
---|
580 | | - |
---|
581 | | -static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) |
---|
582 | | -{ |
---|
583 | | - struct data_queue *queue; |
---|
584 | | - struct queue_entry *entry; |
---|
585 | | - |
---|
586 | | - /* |
---|
587 | | - * Process any trailing TX status reports for IO failures, |
---|
588 | | - * we loop until we find the first non-IO error entry. This |
---|
589 | | - * can either be a frame which is free, is being uploaded, |
---|
590 | | - * or has completed the upload but didn't have an entry |
---|
591 | | - * in the TX_STAT_FIFO register yet. |
---|
592 | | - */ |
---|
593 | | - tx_queue_for_each(rt2x00dev, queue) { |
---|
594 | | - while (!rt2x00queue_empty(queue)) { |
---|
595 | | - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
---|
596 | | - |
---|
597 | | - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
---|
598 | | - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
---|
599 | | - break; |
---|
600 | | - |
---|
601 | | - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || |
---|
602 | | - rt2800usb_entry_txstatus_timeout(entry)) |
---|
603 | | - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); |
---|
604 | | - else |
---|
605 | | - break; |
---|
606 | | - } |
---|
607 | | - } |
---|
608 | | -} |
---|
609 | | - |
---|
610 | 456 | static void rt2800usb_work_txdone(struct work_struct *work) |
---|
611 | 457 | { |
---|
612 | 458 | struct rt2x00_dev *rt2x00dev = |
---|
613 | 459 | container_of(work, struct rt2x00_dev, txdone_work); |
---|
614 | 460 | |
---|
615 | 461 | while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || |
---|
616 | | - rt2800usb_txstatus_timeout(rt2x00dev)) { |
---|
| 462 | + rt2800_txstatus_timeout(rt2x00dev)) { |
---|
617 | 463 | |
---|
618 | | - rt2800usb_txdone(rt2x00dev); |
---|
| 464 | + rt2800_txdone(rt2x00dev, UINT_MAX); |
---|
619 | 465 | |
---|
620 | | - rt2800usb_txdone_nostatus(rt2x00dev); |
---|
| 466 | + rt2800_txdone_nostatus(rt2x00dev); |
---|
621 | 467 | |
---|
622 | 468 | /* |
---|
623 | 469 | * The hw may delay sending the packet after DMA complete |
---|
624 | 470 | * if the medium is busy, thus the TX_STA_FIFO entry is |
---|
625 | 471 | * also delayed -> use a timer to retrieve it. |
---|
626 | 472 | */ |
---|
627 | | - if (rt2800usb_txstatus_pending(rt2x00dev)) |
---|
| 473 | + if (rt2800_txstatus_pending(rt2x00dev)) |
---|
628 | 474 | rt2800usb_async_read_tx_status(rt2x00dev); |
---|
629 | 475 | } |
---|
630 | 476 | } |
---|
.. | .. |
---|
697 | 543 | * stripped it from the frame. Signal this to mac80211. |
---|
698 | 544 | */ |
---|
699 | 545 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; |
---|
700 | | - |
---|
| 546 | + |
---|
701 | 547 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) { |
---|
702 | 548 | rxdesc->flags |= RX_FLAG_DECRYPTED; |
---|
703 | 549 | } else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) { |
---|
704 | 550 | /* |
---|
705 | 551 | * In order to check the Michael Mic, the packet must have |
---|
706 | | - * been decrypted. Mac80211 doesnt check the MMIC failure |
---|
| 552 | + * been decrypted. Mac80211 doesnt check the MMIC failure |
---|
707 | 553 | * flag to initiate MMIC countermeasures if the decoded flag |
---|
708 | 554 | * has not been set. |
---|
709 | 555 | */ |
---|
.. | .. |
---|
808 | 654 | .get_survey = rt2800_get_survey, |
---|
809 | 655 | .get_ringparam = rt2x00mac_get_ringparam, |
---|
810 | 656 | .tx_frames_pending = rt2x00mac_tx_frames_pending, |
---|
| 657 | + .reconfig_complete = rt2x00mac_reconfig_complete, |
---|
811 | 658 | }; |
---|
812 | 659 | |
---|
813 | 660 | static const struct rt2800_ops rt2800usb_rt2800_ops = { |
---|
.. | .. |
---|
823 | 670 | .drv_write_firmware = rt2800usb_write_firmware, |
---|
824 | 671 | .drv_init_registers = rt2800usb_init_registers, |
---|
825 | 672 | .drv_get_txwi = rt2800usb_get_txwi, |
---|
| 673 | + .drv_get_dma_done = rt2800usb_get_dma_done, |
---|
826 | 674 | }; |
---|
827 | 675 | |
---|
828 | 676 | static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { |
---|
.. | .. |
---|
840 | 688 | .link_tuner = rt2800_link_tuner, |
---|
841 | 689 | .gain_calibration = rt2800_gain_calibration, |
---|
842 | 690 | .vco_calibration = rt2800_vco_calibration, |
---|
| 691 | + .watchdog = rt2800_watchdog, |
---|
843 | 692 | .start_queue = rt2800usb_start_queue, |
---|
844 | 693 | .kick_queue = rt2x00usb_kick_queue, |
---|
845 | 694 | .stop_queue = rt2800usb_stop_queue, |
---|
.. | .. |
---|
858 | 707 | .config_erp = rt2800_config_erp, |
---|
859 | 708 | .config_ant = rt2800_config_ant, |
---|
860 | 709 | .config = rt2800_config, |
---|
| 710 | + .pre_reset_hw = rt2800_pre_reset_hw, |
---|
861 | 711 | }; |
---|
862 | 712 | |
---|
863 | 713 | static void rt2800usb_queue_init(struct data_queue *queue) |
---|
.. | .. |
---|
896 | 746 | break; |
---|
897 | 747 | |
---|
898 | 748 | case QID_ATIM: |
---|
899 | | - /* fallthrough */ |
---|
900 | 749 | default: |
---|
901 | 750 | BUG(); |
---|
902 | 751 | break; |
---|
.. | .. |
---|
1237 | 1086 | { USB_DEVICE(0x0846, 0x9013) }, |
---|
1238 | 1087 | { USB_DEVICE(0x0846, 0x9019) }, |
---|
1239 | 1088 | /* Planex */ |
---|
| 1089 | + { USB_DEVICE(0x2019, 0xed14) }, |
---|
1240 | 1090 | { USB_DEVICE(0x2019, 0xed19) }, |
---|
1241 | 1091 | /* Ralink */ |
---|
1242 | 1092 | { USB_DEVICE(0x148f, 0x3573) }, |
---|