| .. | .. |
|---|
| 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) }, |
|---|