| .. | .. |
|---|
| 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) 2010 Ivo van Doorn <IvDoorn@gmail.com> |
|---|
| .. | .. |
|---|
| 13 | 14 | Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> |
|---|
| 14 | 15 | <http://rt2x00.serialmonkey.com> |
|---|
| 15 | 16 | |
|---|
| 16 | | - This program is free software; you can redistribute it and/or modify |
|---|
| 17 | | - it under the terms of the GNU General Public License as published by |
|---|
| 18 | | - the Free Software Foundation; either version 2 of the License, or |
|---|
| 19 | | - (at your option) any later version. |
|---|
| 20 | | - |
|---|
| 21 | | - This program is distributed in the hope that it will be useful, |
|---|
| 22 | | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 23 | | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 24 | | - GNU General Public License for more details. |
|---|
| 25 | | - |
|---|
| 26 | | - You should have received a copy of the GNU General Public License |
|---|
| 27 | | - along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 28 | 17 | */ |
|---|
| 29 | 18 | |
|---|
| 30 | 19 | /* |
|---|
| .. | .. |
|---|
| 40 | 29 | #include "rt2x00.h" |
|---|
| 41 | 30 | #include "rt2800lib.h" |
|---|
| 42 | 31 | #include "rt2800.h" |
|---|
| 32 | + |
|---|
| 33 | +static bool modparam_watchdog; |
|---|
| 34 | +module_param_named(watchdog, modparam_watchdog, bool, S_IRUGO); |
|---|
| 35 | +MODULE_PARM_DESC(watchdog, "Enable watchdog to detect tx/rx hangs and reset hardware if detected"); |
|---|
| 43 | 36 | |
|---|
| 44 | 37 | /* |
|---|
| 45 | 38 | * Register access. |
|---|
| .. | .. |
|---|
| 381 | 374 | wiphy_name(rt2x00dev->hw->wiphy), word)) |
|---|
| 382 | 375 | return 0; |
|---|
| 383 | 376 | |
|---|
| 384 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 377 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 378 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 385 | 379 | map = rt2800_eeprom_map_ext; |
|---|
| 386 | 380 | else |
|---|
| 387 | 381 | map = rt2800_eeprom_map; |
|---|
| .. | .. |
|---|
| 590 | 584 | { |
|---|
| 591 | 585 | switch (rt2x00dev->chip.rt) { |
|---|
| 592 | 586 | case RT3593: |
|---|
| 587 | + case RT3883: |
|---|
| 593 | 588 | *txwi_size = TXWI_DESC_SIZE_4WORDS; |
|---|
| 594 | 589 | *rxwi_size = RXWI_DESC_SIZE_5WORDS; |
|---|
| 595 | 590 | break; |
|---|
| .. | .. |
|---|
| 933 | 928 | switch (rt2x00_get_field32(status, TX_STA_FIFO_PHYMODE)) { |
|---|
| 934 | 929 | case RATE_MODE_HT_GREENFIELD: |
|---|
| 935 | 930 | flags |= IEEE80211_TX_RC_GREEN_FIELD; |
|---|
| 936 | | - /* fall through */ |
|---|
| 931 | + fallthrough; |
|---|
| 937 | 932 | case RATE_MODE_HT_MIX: |
|---|
| 938 | 933 | flags |= IEEE80211_TX_RC_MCS; |
|---|
| 939 | 934 | break; |
|---|
| .. | .. |
|---|
| 955 | 950 | |
|---|
| 956 | 951 | skbdesc->tx_rate_idx = idx; |
|---|
| 957 | 952 | skbdesc->tx_rate_flags = flags; |
|---|
| 953 | +} |
|---|
| 954 | + |
|---|
| 955 | +static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) |
|---|
| 956 | +{ |
|---|
| 957 | + __le32 *txwi; |
|---|
| 958 | + u32 word; |
|---|
| 959 | + int wcid, ack, pid; |
|---|
| 960 | + int tx_wcid, tx_ack, tx_pid, is_agg; |
|---|
| 961 | + |
|---|
| 962 | + /* |
|---|
| 963 | + * This frames has returned with an IO error, |
|---|
| 964 | + * so the status report is not intended for this |
|---|
| 965 | + * frame. |
|---|
| 966 | + */ |
|---|
| 967 | + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) |
|---|
| 968 | + return false; |
|---|
| 969 | + |
|---|
| 970 | + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); |
|---|
| 971 | + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); |
|---|
| 972 | + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); |
|---|
| 973 | + is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); |
|---|
| 974 | + |
|---|
| 975 | + /* |
|---|
| 976 | + * Validate if this TX status report is intended for |
|---|
| 977 | + * this entry by comparing the WCID/ACK/PID fields. |
|---|
| 978 | + */ |
|---|
| 979 | + txwi = rt2800_drv_get_txwi(entry); |
|---|
| 980 | + |
|---|
| 981 | + word = rt2x00_desc_read(txwi, 1); |
|---|
| 982 | + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); |
|---|
| 983 | + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); |
|---|
| 984 | + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); |
|---|
| 985 | + |
|---|
| 986 | + if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { |
|---|
| 987 | + rt2x00_dbg(entry->queue->rt2x00dev, |
|---|
| 988 | + "TX status report missed for queue %d entry %d\n", |
|---|
| 989 | + entry->queue->qid, entry->entry_idx); |
|---|
| 990 | + return false; |
|---|
| 991 | + } |
|---|
| 992 | + |
|---|
| 993 | + return true; |
|---|
| 958 | 994 | } |
|---|
| 959 | 995 | |
|---|
| 960 | 996 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, |
|---|
| .. | .. |
|---|
| 1058 | 1094 | } |
|---|
| 1059 | 1095 | } |
|---|
| 1060 | 1096 | EXPORT_SYMBOL_GPL(rt2800_txdone_entry); |
|---|
| 1097 | + |
|---|
| 1098 | +void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota) |
|---|
| 1099 | +{ |
|---|
| 1100 | + struct data_queue *queue; |
|---|
| 1101 | + struct queue_entry *entry; |
|---|
| 1102 | + u32 reg; |
|---|
| 1103 | + u8 qid; |
|---|
| 1104 | + bool match; |
|---|
| 1105 | + |
|---|
| 1106 | + while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { |
|---|
| 1107 | + /* |
|---|
| 1108 | + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is |
|---|
| 1109 | + * guaranteed to be one of the TX QIDs . |
|---|
| 1110 | + */ |
|---|
| 1111 | + qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); |
|---|
| 1112 | + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); |
|---|
| 1113 | + |
|---|
| 1114 | + if (unlikely(rt2x00queue_empty(queue))) { |
|---|
| 1115 | + rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", |
|---|
| 1116 | + qid); |
|---|
| 1117 | + break; |
|---|
| 1118 | + } |
|---|
| 1119 | + |
|---|
| 1120 | + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
|---|
| 1121 | + |
|---|
| 1122 | + if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
|---|
| 1123 | + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { |
|---|
| 1124 | + rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", |
|---|
| 1125 | + entry->entry_idx, qid); |
|---|
| 1126 | + break; |
|---|
| 1127 | + } |
|---|
| 1128 | + |
|---|
| 1129 | + match = rt2800_txdone_entry_check(entry, reg); |
|---|
| 1130 | + rt2800_txdone_entry(entry, reg, rt2800_drv_get_txwi(entry), match); |
|---|
| 1131 | + } |
|---|
| 1132 | +} |
|---|
| 1133 | +EXPORT_SYMBOL_GPL(rt2800_txdone); |
|---|
| 1134 | + |
|---|
| 1135 | +static inline bool rt2800_entry_txstatus_timeout(struct rt2x00_dev *rt2x00dev, |
|---|
| 1136 | + struct queue_entry *entry) |
|---|
| 1137 | +{ |
|---|
| 1138 | + bool ret; |
|---|
| 1139 | + unsigned long tout; |
|---|
| 1140 | + |
|---|
| 1141 | + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
|---|
| 1142 | + return false; |
|---|
| 1143 | + |
|---|
| 1144 | + if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) |
|---|
| 1145 | + tout = msecs_to_jiffies(50); |
|---|
| 1146 | + else |
|---|
| 1147 | + tout = msecs_to_jiffies(2000); |
|---|
| 1148 | + |
|---|
| 1149 | + ret = time_after(jiffies, entry->last_action + tout); |
|---|
| 1150 | + if (unlikely(ret)) |
|---|
| 1151 | + rt2x00_dbg(entry->queue->rt2x00dev, |
|---|
| 1152 | + "TX status timeout for entry %d in queue %d\n", |
|---|
| 1153 | + entry->entry_idx, entry->queue->qid); |
|---|
| 1154 | + return ret; |
|---|
| 1155 | +} |
|---|
| 1156 | + |
|---|
| 1157 | +bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) |
|---|
| 1158 | +{ |
|---|
| 1159 | + struct data_queue *queue; |
|---|
| 1160 | + struct queue_entry *entry; |
|---|
| 1161 | + |
|---|
| 1162 | + tx_queue_for_each(rt2x00dev, queue) { |
|---|
| 1163 | + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
|---|
| 1164 | + if (rt2800_entry_txstatus_timeout(rt2x00dev, entry)) |
|---|
| 1165 | + return true; |
|---|
| 1166 | + } |
|---|
| 1167 | + |
|---|
| 1168 | + return false; |
|---|
| 1169 | +} |
|---|
| 1170 | +EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout); |
|---|
| 1171 | + |
|---|
| 1172 | +/* |
|---|
| 1173 | + * test if there is an entry in any TX queue for which DMA is done |
|---|
| 1174 | + * but the TX status has not been returned yet |
|---|
| 1175 | + */ |
|---|
| 1176 | +bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev) |
|---|
| 1177 | +{ |
|---|
| 1178 | + struct data_queue *queue; |
|---|
| 1179 | + |
|---|
| 1180 | + tx_queue_for_each(rt2x00dev, queue) { |
|---|
| 1181 | + if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) != |
|---|
| 1182 | + rt2x00queue_get_entry(queue, Q_INDEX_DONE)) |
|---|
| 1183 | + return true; |
|---|
| 1184 | + } |
|---|
| 1185 | + return false; |
|---|
| 1186 | +} |
|---|
| 1187 | +EXPORT_SYMBOL_GPL(rt2800_txstatus_pending); |
|---|
| 1188 | + |
|---|
| 1189 | +void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev) |
|---|
| 1190 | +{ |
|---|
| 1191 | + struct data_queue *queue; |
|---|
| 1192 | + struct queue_entry *entry; |
|---|
| 1193 | + |
|---|
| 1194 | + /* |
|---|
| 1195 | + * Process any trailing TX status reports for IO failures, |
|---|
| 1196 | + * we loop until we find the first non-IO error entry. This |
|---|
| 1197 | + * can either be a frame which is free, is being uploaded, |
|---|
| 1198 | + * or has completed the upload but didn't have an entry |
|---|
| 1199 | + * in the TX_STAT_FIFO register yet. |
|---|
| 1200 | + */ |
|---|
| 1201 | + tx_queue_for_each(rt2x00dev, queue) { |
|---|
| 1202 | + while (!rt2x00queue_empty(queue)) { |
|---|
| 1203 | + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
|---|
| 1204 | + |
|---|
| 1205 | + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || |
|---|
| 1206 | + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) |
|---|
| 1207 | + break; |
|---|
| 1208 | + |
|---|
| 1209 | + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || |
|---|
| 1210 | + rt2800_entry_txstatus_timeout(rt2x00dev, entry)) |
|---|
| 1211 | + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); |
|---|
| 1212 | + else |
|---|
| 1213 | + break; |
|---|
| 1214 | + } |
|---|
| 1215 | + } |
|---|
| 1216 | +} |
|---|
| 1217 | +EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus); |
|---|
| 1218 | + |
|---|
| 1219 | +static int rt2800_check_hung(struct data_queue *queue) |
|---|
| 1220 | +{ |
|---|
| 1221 | + unsigned int cur_idx = rt2800_drv_get_dma_done(queue); |
|---|
| 1222 | + |
|---|
| 1223 | + if (queue->wd_idx != cur_idx) |
|---|
| 1224 | + queue->wd_count = 0; |
|---|
| 1225 | + else |
|---|
| 1226 | + queue->wd_count++; |
|---|
| 1227 | + |
|---|
| 1228 | + return queue->wd_count > 16; |
|---|
| 1229 | +} |
|---|
| 1230 | + |
|---|
| 1231 | +void rt2800_watchdog(struct rt2x00_dev *rt2x00dev) |
|---|
| 1232 | +{ |
|---|
| 1233 | + struct data_queue *queue; |
|---|
| 1234 | + bool hung_tx = false; |
|---|
| 1235 | + bool hung_rx = false; |
|---|
| 1236 | + |
|---|
| 1237 | + if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) |
|---|
| 1238 | + return; |
|---|
| 1239 | + |
|---|
| 1240 | + queue_for_each(rt2x00dev, queue) { |
|---|
| 1241 | + switch (queue->qid) { |
|---|
| 1242 | + case QID_AC_VO: |
|---|
| 1243 | + case QID_AC_VI: |
|---|
| 1244 | + case QID_AC_BE: |
|---|
| 1245 | + case QID_AC_BK: |
|---|
| 1246 | + case QID_MGMT: |
|---|
| 1247 | + if (rt2x00queue_empty(queue)) |
|---|
| 1248 | + continue; |
|---|
| 1249 | + hung_tx = rt2800_check_hung(queue); |
|---|
| 1250 | + break; |
|---|
| 1251 | + case QID_RX: |
|---|
| 1252 | + /* For station mode we should reactive at least |
|---|
| 1253 | + * beacons. TODO: need to find good way detect |
|---|
| 1254 | + * RX hung for AP mode. |
|---|
| 1255 | + */ |
|---|
| 1256 | + if (rt2x00dev->intf_sta_count == 0) |
|---|
| 1257 | + continue; |
|---|
| 1258 | + hung_rx = rt2800_check_hung(queue); |
|---|
| 1259 | + break; |
|---|
| 1260 | + default: |
|---|
| 1261 | + break; |
|---|
| 1262 | + } |
|---|
| 1263 | + } |
|---|
| 1264 | + |
|---|
| 1265 | + if (hung_tx) |
|---|
| 1266 | + rt2x00_warn(rt2x00dev, "Watchdog TX hung detected\n"); |
|---|
| 1267 | + |
|---|
| 1268 | + if (hung_rx) |
|---|
| 1269 | + rt2x00_warn(rt2x00dev, "Watchdog RX hung detected\n"); |
|---|
| 1270 | + |
|---|
| 1271 | + if (hung_tx || hung_rx) |
|---|
| 1272 | + ieee80211_restart_hw(rt2x00dev->hw); |
|---|
| 1273 | +} |
|---|
| 1274 | +EXPORT_SYMBOL_GPL(rt2800_watchdog); |
|---|
| 1061 | 1275 | |
|---|
| 1062 | 1276 | static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, |
|---|
| 1063 | 1277 | unsigned int index) |
|---|
| .. | .. |
|---|
| 1438 | 1652 | rt2800_register_write(rt2x00dev, offset, reg); |
|---|
| 1439 | 1653 | } |
|---|
| 1440 | 1654 | |
|---|
| 1655 | + if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags)) |
|---|
| 1656 | + return; |
|---|
| 1657 | + |
|---|
| 1441 | 1658 | offset = MAC_IVEIV_ENTRY(key->hw_key_idx); |
|---|
| 1442 | 1659 | |
|---|
| 1443 | 1660 | memset(&iveiv_entry, 0, sizeof(iveiv_entry)); |
|---|
| .. | .. |
|---|
| 1447 | 1664 | iveiv_entry.iv[3] |= 0x20; |
|---|
| 1448 | 1665 | iveiv_entry.iv[3] |= key->keyidx << 6; |
|---|
| 1449 | 1666 | rt2800_register_multiwrite(rt2x00dev, offset, |
|---|
| 1450 | | - &iveiv_entry, sizeof(iveiv_entry)); |
|---|
| 1667 | + &iveiv_entry, sizeof(iveiv_entry)); |
|---|
| 1451 | 1668 | } |
|---|
| 1452 | 1669 | |
|---|
| 1453 | 1670 | int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, |
|---|
| .. | .. |
|---|
| 1635 | 1852 | return 0; |
|---|
| 1636 | 1853 | } |
|---|
| 1637 | 1854 | EXPORT_SYMBOL_GPL(rt2800_sta_remove); |
|---|
| 1855 | + |
|---|
| 1856 | +void rt2800_pre_reset_hw(struct rt2x00_dev *rt2x00dev) |
|---|
| 1857 | +{ |
|---|
| 1858 | + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; |
|---|
| 1859 | + struct data_queue *queue = rt2x00dev->bcn; |
|---|
| 1860 | + struct queue_entry *entry; |
|---|
| 1861 | + int i, wcid; |
|---|
| 1862 | + |
|---|
| 1863 | + for (wcid = WCID_START; wcid < WCID_END; wcid++) { |
|---|
| 1864 | + drv_data->wcid_to_sta[wcid - WCID_START] = NULL; |
|---|
| 1865 | + __clear_bit(wcid - WCID_START, drv_data->sta_ids); |
|---|
| 1866 | + } |
|---|
| 1867 | + |
|---|
| 1868 | + for (i = 0; i < queue->limit; i++) { |
|---|
| 1869 | + entry = &queue->entries[i]; |
|---|
| 1870 | + clear_bit(ENTRY_BCN_ASSIGNED, &entry->flags); |
|---|
| 1871 | + } |
|---|
| 1872 | +} |
|---|
| 1873 | +EXPORT_SYMBOL_GPL(rt2800_pre_reset_hw); |
|---|
| 1638 | 1874 | |
|---|
| 1639 | 1875 | void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, |
|---|
| 1640 | 1876 | const unsigned int filter_flags) |
|---|
| .. | .. |
|---|
| 2018 | 2254 | rt2800_bbp_write(rt2x00dev, 3, r3); |
|---|
| 2019 | 2255 | rt2800_bbp_write(rt2x00dev, 1, r1); |
|---|
| 2020 | 2256 | |
|---|
| 2021 | | - if (rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 2257 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 2258 | + rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 2022 | 2259 | if (ant->rx_chain_num == 1) |
|---|
| 2023 | 2260 | rt2800_bbp_write(rt2x00dev, 86, 0x00); |
|---|
| 2024 | 2261 | else |
|---|
| .. | .. |
|---|
| 2040 | 2277 | eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_LNA); |
|---|
| 2041 | 2278 | lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); |
|---|
| 2042 | 2279 | } else if (libconf->rf.channel <= 128) { |
|---|
| 2043 | | - if (rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 2280 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 2281 | + rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 2044 | 2282 | eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); |
|---|
| 2045 | 2283 | lna_gain = rt2x00_get_field16(eeprom, |
|---|
| 2046 | 2284 | EEPROM_EXT_LNA2_A1); |
|---|
| .. | .. |
|---|
| 2050 | 2288 | EEPROM_RSSI_BG2_LNA_A1); |
|---|
| 2051 | 2289 | } |
|---|
| 2052 | 2290 | } else { |
|---|
| 2053 | | - if (rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 2291 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 2292 | + rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 2054 | 2293 | eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); |
|---|
| 2055 | 2294 | lna_gain = rt2x00_get_field16(eeprom, |
|---|
| 2056 | 2295 | EEPROM_EXT_LNA2_A2); |
|---|
| .. | .. |
|---|
| 2328 | 2567 | switch (rt2x00dev->default_ant.tx_chain_num) { |
|---|
| 2329 | 2568 | case 1: |
|---|
| 2330 | 2569 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); |
|---|
| 2570 | + fallthrough; |
|---|
| 2331 | 2571 | case 2: |
|---|
| 2332 | 2572 | rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); |
|---|
| 2333 | 2573 | break; |
|---|
| .. | .. |
|---|
| 2336 | 2576 | switch (rt2x00dev->default_ant.rx_chain_num) { |
|---|
| 2337 | 2577 | case 1: |
|---|
| 2338 | 2578 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); |
|---|
| 2579 | + fallthrough; |
|---|
| 2339 | 2580 | case 2: |
|---|
| 2340 | 2581 | rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); |
|---|
| 2341 | 2582 | break; |
|---|
| .. | .. |
|---|
| 2527 | 2768 | switch (rt2x00dev->default_ant.tx_chain_num) { |
|---|
| 2528 | 2769 | case 3: |
|---|
| 2529 | 2770 | rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); |
|---|
| 2530 | | - /* fallthrough */ |
|---|
| 2771 | + fallthrough; |
|---|
| 2531 | 2772 | case 2: |
|---|
| 2532 | 2773 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); |
|---|
| 2533 | | - /* fallthrough */ |
|---|
| 2774 | + fallthrough; |
|---|
| 2534 | 2775 | case 1: |
|---|
| 2535 | 2776 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); |
|---|
| 2536 | 2777 | break; |
|---|
| .. | .. |
|---|
| 2539 | 2780 | switch (rt2x00dev->default_ant.rx_chain_num) { |
|---|
| 2540 | 2781 | case 3: |
|---|
| 2541 | 2782 | rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); |
|---|
| 2542 | | - /* fallthrough */ |
|---|
| 2783 | + fallthrough; |
|---|
| 2543 | 2784 | case 2: |
|---|
| 2544 | 2785 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); |
|---|
| 2545 | | - /* fallthrough */ |
|---|
| 2786 | + fallthrough; |
|---|
| 2546 | 2787 | case 1: |
|---|
| 2547 | 2788 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); |
|---|
| 2548 | 2789 | break; |
|---|
| .. | .. |
|---|
| 2716 | 2957 | } |
|---|
| 2717 | 2958 | } |
|---|
| 2718 | 2959 | |
|---|
| 2960 | +static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev, |
|---|
| 2961 | + struct ieee80211_conf *conf, |
|---|
| 2962 | + struct rf_channel *rf, |
|---|
| 2963 | + struct channel_info *info) |
|---|
| 2964 | +{ |
|---|
| 2965 | + u8 rfcsr; |
|---|
| 2966 | + u8 bbp; |
|---|
| 2967 | + u8 pwr1, pwr2, pwr3; |
|---|
| 2968 | + |
|---|
| 2969 | + const bool txbf_enabled = false; /* TODO */ |
|---|
| 2970 | + |
|---|
| 2971 | + /* TODO: add band selection */ |
|---|
| 2972 | + |
|---|
| 2973 | + if (rf->channel <= 14) |
|---|
| 2974 | + rt2800_rfcsr_write(rt2x00dev, 6, 0x40); |
|---|
| 2975 | + else if (rf->channel < 132) |
|---|
| 2976 | + rt2800_rfcsr_write(rt2x00dev, 6, 0x80); |
|---|
| 2977 | + else |
|---|
| 2978 | + rt2800_rfcsr_write(rt2x00dev, 6, 0x40); |
|---|
| 2979 | + |
|---|
| 2980 | + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); |
|---|
| 2981 | + rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); |
|---|
| 2982 | + |
|---|
| 2983 | + if (rf->channel <= 14) |
|---|
| 2984 | + rt2800_rfcsr_write(rt2x00dev, 11, 0x46); |
|---|
| 2985 | + else |
|---|
| 2986 | + rt2800_rfcsr_write(rt2x00dev, 11, 0x48); |
|---|
| 2987 | + |
|---|
| 2988 | + if (rf->channel <= 14) |
|---|
| 2989 | + rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); |
|---|
| 2990 | + else |
|---|
| 2991 | + rt2800_rfcsr_write(rt2x00dev, 12, 0x52); |
|---|
| 2992 | + |
|---|
| 2993 | + rt2800_rfcsr_write(rt2x00dev, 13, 0x12); |
|---|
| 2994 | + |
|---|
| 2995 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); |
|---|
| 2996 | + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); |
|---|
| 2997 | + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); |
|---|
| 2998 | + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); |
|---|
| 2999 | + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); |
|---|
| 3000 | + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); |
|---|
| 3001 | + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); |
|---|
| 3002 | + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); |
|---|
| 3003 | + rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); |
|---|
| 3004 | + |
|---|
| 3005 | + switch (rt2x00dev->default_ant.tx_chain_num) { |
|---|
| 3006 | + case 3: |
|---|
| 3007 | + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); |
|---|
| 3008 | + fallthrough; |
|---|
| 3009 | + case 2: |
|---|
| 3010 | + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); |
|---|
| 3011 | + fallthrough; |
|---|
| 3012 | + case 1: |
|---|
| 3013 | + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); |
|---|
| 3014 | + break; |
|---|
| 3015 | + } |
|---|
| 3016 | + |
|---|
| 3017 | + switch (rt2x00dev->default_ant.rx_chain_num) { |
|---|
| 3018 | + case 3: |
|---|
| 3019 | + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); |
|---|
| 3020 | + fallthrough; |
|---|
| 3021 | + case 2: |
|---|
| 3022 | + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); |
|---|
| 3023 | + fallthrough; |
|---|
| 3024 | + case 1: |
|---|
| 3025 | + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); |
|---|
| 3026 | + break; |
|---|
| 3027 | + } |
|---|
| 3028 | + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); |
|---|
| 3029 | + |
|---|
| 3030 | + rt2800_freq_cal_mode1(rt2x00dev); |
|---|
| 3031 | + |
|---|
| 3032 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 30); |
|---|
| 3033 | + if (!conf_is_ht40(conf)) |
|---|
| 3034 | + rfcsr &= ~(0x06); |
|---|
| 3035 | + else |
|---|
| 3036 | + rfcsr |= 0x06; |
|---|
| 3037 | + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); |
|---|
| 3038 | + |
|---|
| 3039 | + if (rf->channel <= 14) |
|---|
| 3040 | + rt2800_rfcsr_write(rt2x00dev, 31, 0xa0); |
|---|
| 3041 | + else |
|---|
| 3042 | + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); |
|---|
| 3043 | + |
|---|
| 3044 | + if (conf_is_ht40(conf)) |
|---|
| 3045 | + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); |
|---|
| 3046 | + else |
|---|
| 3047 | + rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); |
|---|
| 3048 | + |
|---|
| 3049 | + if (rf->channel <= 14) |
|---|
| 3050 | + rt2800_rfcsr_write(rt2x00dev, 34, 0x3c); |
|---|
| 3051 | + else |
|---|
| 3052 | + rt2800_rfcsr_write(rt2x00dev, 34, 0x20); |
|---|
| 3053 | + |
|---|
| 3054 | + /* loopback RF_BS */ |
|---|
| 3055 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 36); |
|---|
| 3056 | + if (rf->channel <= 14) |
|---|
| 3057 | + rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1); |
|---|
| 3058 | + else |
|---|
| 3059 | + rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0); |
|---|
| 3060 | + rt2800_rfcsr_write(rt2x00dev, 36, rfcsr); |
|---|
| 3061 | + |
|---|
| 3062 | + if (rf->channel <= 14) |
|---|
| 3063 | + rfcsr = 0x23; |
|---|
| 3064 | + else if (rf->channel < 100) |
|---|
| 3065 | + rfcsr = 0x36; |
|---|
| 3066 | + else if (rf->channel < 132) |
|---|
| 3067 | + rfcsr = 0x32; |
|---|
| 3068 | + else |
|---|
| 3069 | + rfcsr = 0x30; |
|---|
| 3070 | + |
|---|
| 3071 | + if (txbf_enabled) |
|---|
| 3072 | + rfcsr |= 0x40; |
|---|
| 3073 | + |
|---|
| 3074 | + rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); |
|---|
| 3075 | + |
|---|
| 3076 | + if (rf->channel <= 14) |
|---|
| 3077 | + rt2800_rfcsr_write(rt2x00dev, 44, 0x93); |
|---|
| 3078 | + else |
|---|
| 3079 | + rt2800_rfcsr_write(rt2x00dev, 44, 0x9b); |
|---|
| 3080 | + |
|---|
| 3081 | + if (rf->channel <= 14) |
|---|
| 3082 | + rfcsr = 0xbb; |
|---|
| 3083 | + else if (rf->channel < 100) |
|---|
| 3084 | + rfcsr = 0xeb; |
|---|
| 3085 | + else if (rf->channel < 132) |
|---|
| 3086 | + rfcsr = 0xb3; |
|---|
| 3087 | + else |
|---|
| 3088 | + rfcsr = 0x9b; |
|---|
| 3089 | + rt2800_rfcsr_write(rt2x00dev, 45, rfcsr); |
|---|
| 3090 | + |
|---|
| 3091 | + if (rf->channel <= 14) |
|---|
| 3092 | + rfcsr = 0x8e; |
|---|
| 3093 | + else |
|---|
| 3094 | + rfcsr = 0x8a; |
|---|
| 3095 | + |
|---|
| 3096 | + if (txbf_enabled) |
|---|
| 3097 | + rfcsr |= 0x20; |
|---|
| 3098 | + |
|---|
| 3099 | + rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); |
|---|
| 3100 | + |
|---|
| 3101 | + rt2800_rfcsr_write(rt2x00dev, 50, 0x86); |
|---|
| 3102 | + |
|---|
| 3103 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 51); |
|---|
| 3104 | + if (rf->channel <= 14) |
|---|
| 3105 | + rt2800_rfcsr_write(rt2x00dev, 51, 0x75); |
|---|
| 3106 | + else |
|---|
| 3107 | + rt2800_rfcsr_write(rt2x00dev, 51, 0x51); |
|---|
| 3108 | + |
|---|
| 3109 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 52); |
|---|
| 3110 | + if (rf->channel <= 14) |
|---|
| 3111 | + rt2800_rfcsr_write(rt2x00dev, 52, 0x45); |
|---|
| 3112 | + else |
|---|
| 3113 | + rt2800_rfcsr_write(rt2x00dev, 52, 0x05); |
|---|
| 3114 | + |
|---|
| 3115 | + if (rf->channel <= 14) { |
|---|
| 3116 | + pwr1 = info->default_power1 & 0x1f; |
|---|
| 3117 | + pwr2 = info->default_power2 & 0x1f; |
|---|
| 3118 | + pwr3 = info->default_power3 & 0x1f; |
|---|
| 3119 | + } else { |
|---|
| 3120 | + pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) | |
|---|
| 3121 | + (info->default_power1 & 0x7); |
|---|
| 3122 | + pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) | |
|---|
| 3123 | + (info->default_power2 & 0x7); |
|---|
| 3124 | + pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) | |
|---|
| 3125 | + (info->default_power3 & 0x7); |
|---|
| 3126 | + } |
|---|
| 3127 | + |
|---|
| 3128 | + rt2800_rfcsr_write(rt2x00dev, 53, pwr1); |
|---|
| 3129 | + rt2800_rfcsr_write(rt2x00dev, 54, pwr2); |
|---|
| 3130 | + rt2800_rfcsr_write(rt2x00dev, 55, pwr3); |
|---|
| 3131 | + |
|---|
| 3132 | + rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n", |
|---|
| 3133 | + rf->channel, pwr1, pwr2, pwr3); |
|---|
| 3134 | + |
|---|
| 3135 | + bbp = (info->default_power1 >> 5) | |
|---|
| 3136 | + ((info->default_power2 & 0xe0) >> 1); |
|---|
| 3137 | + rt2800_bbp_write(rt2x00dev, 109, bbp); |
|---|
| 3138 | + |
|---|
| 3139 | + bbp = rt2800_bbp_read(rt2x00dev, 110); |
|---|
| 3140 | + bbp &= 0x0f; |
|---|
| 3141 | + bbp |= (info->default_power3 & 0xe0) >> 1; |
|---|
| 3142 | + rt2800_bbp_write(rt2x00dev, 110, bbp); |
|---|
| 3143 | + |
|---|
| 3144 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 57); |
|---|
| 3145 | + if (rf->channel <= 14) |
|---|
| 3146 | + rt2800_rfcsr_write(rt2x00dev, 57, 0x6e); |
|---|
| 3147 | + else |
|---|
| 3148 | + rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); |
|---|
| 3149 | + |
|---|
| 3150 | + /* Enable RF tuning */ |
|---|
| 3151 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 3); |
|---|
| 3152 | + rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); |
|---|
| 3153 | + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); |
|---|
| 3154 | + |
|---|
| 3155 | + udelay(2000); |
|---|
| 3156 | + |
|---|
| 3157 | + bbp = rt2800_bbp_read(rt2x00dev, 49); |
|---|
| 3158 | + /* clear update flag */ |
|---|
| 3159 | + rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe); |
|---|
| 3160 | + rt2800_bbp_write(rt2x00dev, 49, bbp); |
|---|
| 3161 | + |
|---|
| 3162 | + /* TODO: add calibration for TxBF */ |
|---|
| 3163 | +} |
|---|
| 3164 | + |
|---|
| 2719 | 3165 | #define POWER_BOUND 0x27 |
|---|
| 2720 | 3166 | #define POWER_BOUND_5G 0x2b |
|---|
| 2721 | 3167 | |
|---|
| .. | .. |
|---|
| 2810 | 3256 | struct channel_info *info) |
|---|
| 2811 | 3257 | { |
|---|
| 2812 | 3258 | u8 rfcsr; |
|---|
| 3259 | + int idx = rf->channel-1; |
|---|
| 2813 | 3260 | |
|---|
| 2814 | 3261 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); |
|---|
| 2815 | 3262 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); |
|---|
| .. | .. |
|---|
| 2847 | 3294 | |
|---|
| 2848 | 3295 | rt2800_freq_cal_mode1(rt2x00dev); |
|---|
| 2849 | 3296 | |
|---|
| 2850 | | - if (rf->channel <= 14) { |
|---|
| 2851 | | - int idx = rf->channel-1; |
|---|
| 3297 | + if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { |
|---|
| 3298 | + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
|---|
| 3299 | + /* r55/r59 value array of channel 1~14 */ |
|---|
| 3300 | + static const char r55_bt_rev[] = {0x83, 0x83, |
|---|
| 3301 | + 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, |
|---|
| 3302 | + 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; |
|---|
| 3303 | + static const char r59_bt_rev[] = {0x0e, 0x0e, |
|---|
| 3304 | + 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, |
|---|
| 3305 | + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; |
|---|
| 2852 | 3306 | |
|---|
| 2853 | | - if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { |
|---|
| 2854 | | - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
|---|
| 2855 | | - /* r55/r59 value array of channel 1~14 */ |
|---|
| 2856 | | - static const char r55_bt_rev[] = {0x83, 0x83, |
|---|
| 2857 | | - 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, |
|---|
| 2858 | | - 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; |
|---|
| 2859 | | - static const char r59_bt_rev[] = {0x0e, 0x0e, |
|---|
| 2860 | | - 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, |
|---|
| 2861 | | - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; |
|---|
| 2862 | | - |
|---|
| 2863 | | - rt2800_rfcsr_write(rt2x00dev, 55, |
|---|
| 2864 | | - r55_bt_rev[idx]); |
|---|
| 2865 | | - rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 2866 | | - r59_bt_rev[idx]); |
|---|
| 2867 | | - } else { |
|---|
| 2868 | | - static const char r59_bt[] = {0x8b, 0x8b, 0x8b, |
|---|
| 2869 | | - 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, |
|---|
| 2870 | | - 0x88, 0x88, 0x86, 0x85, 0x84}; |
|---|
| 2871 | | - |
|---|
| 2872 | | - rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); |
|---|
| 2873 | | - } |
|---|
| 3307 | + rt2800_rfcsr_write(rt2x00dev, 55, |
|---|
| 3308 | + r55_bt_rev[idx]); |
|---|
| 3309 | + rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 3310 | + r59_bt_rev[idx]); |
|---|
| 2874 | 3311 | } else { |
|---|
| 2875 | | - if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
|---|
| 2876 | | - static const char r55_nonbt_rev[] = {0x23, 0x23, |
|---|
| 2877 | | - 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, |
|---|
| 2878 | | - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; |
|---|
| 2879 | | - static const char r59_nonbt_rev[] = {0x07, 0x07, |
|---|
| 2880 | | - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
|---|
| 2881 | | - 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; |
|---|
| 3312 | + static const char r59_bt[] = {0x8b, 0x8b, 0x8b, |
|---|
| 3313 | + 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, |
|---|
| 3314 | + 0x88, 0x88, 0x86, 0x85, 0x84}; |
|---|
| 2882 | 3315 | |
|---|
| 2883 | | - rt2800_rfcsr_write(rt2x00dev, 55, |
|---|
| 2884 | | - r55_nonbt_rev[idx]); |
|---|
| 2885 | | - rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 2886 | | - r59_nonbt_rev[idx]); |
|---|
| 2887 | | - } else if (rt2x00_rt(rt2x00dev, RT5390) || |
|---|
| 2888 | | - rt2x00_rt(rt2x00dev, RT5392) || |
|---|
| 2889 | | - rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 2890 | | - static const char r59_non_bt[] = {0x8f, 0x8f, |
|---|
| 2891 | | - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, |
|---|
| 2892 | | - 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; |
|---|
| 3316 | + rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); |
|---|
| 3317 | + } |
|---|
| 3318 | + } else { |
|---|
| 3319 | + if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { |
|---|
| 3320 | + static const char r55_nonbt_rev[] = {0x23, 0x23, |
|---|
| 3321 | + 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, |
|---|
| 3322 | + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; |
|---|
| 3323 | + static const char r59_nonbt_rev[] = {0x07, 0x07, |
|---|
| 3324 | + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
|---|
| 3325 | + 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; |
|---|
| 2893 | 3326 | |
|---|
| 2894 | | - rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 2895 | | - r59_non_bt[idx]); |
|---|
| 2896 | | - } else if (rt2x00_rt(rt2x00dev, RT5350)) { |
|---|
| 2897 | | - static const char r59_non_bt[] = {0x0b, 0x0b, |
|---|
| 2898 | | - 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, |
|---|
| 2899 | | - 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06}; |
|---|
| 3327 | + rt2800_rfcsr_write(rt2x00dev, 55, |
|---|
| 3328 | + r55_nonbt_rev[idx]); |
|---|
| 3329 | + rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 3330 | + r59_nonbt_rev[idx]); |
|---|
| 3331 | + } else if (rt2x00_rt(rt2x00dev, RT5390) || |
|---|
| 3332 | + rt2x00_rt(rt2x00dev, RT5392) || |
|---|
| 3333 | + rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 3334 | + static const char r59_non_bt[] = {0x8f, 0x8f, |
|---|
| 3335 | + 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, |
|---|
| 3336 | + 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; |
|---|
| 2900 | 3337 | |
|---|
| 2901 | | - rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 2902 | | - r59_non_bt[idx]); |
|---|
| 2903 | | - } |
|---|
| 3338 | + rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 3339 | + r59_non_bt[idx]); |
|---|
| 3340 | + } else if (rt2x00_rt(rt2x00dev, RT5350)) { |
|---|
| 3341 | + static const char r59_non_bt[] = {0x0b, 0x0b, |
|---|
| 3342 | + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, |
|---|
| 3343 | + 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06}; |
|---|
| 3344 | + |
|---|
| 3345 | + rt2800_rfcsr_write(rt2x00dev, 59, |
|---|
| 3346 | + r59_non_bt[idx]); |
|---|
| 2904 | 3347 | } |
|---|
| 2905 | 3348 | } |
|---|
| 2906 | 3349 | } |
|---|
| .. | .. |
|---|
| 3522 | 3965 | unsigned int channel, |
|---|
| 3523 | 3966 | char txpower) |
|---|
| 3524 | 3967 | { |
|---|
| 3525 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 3968 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 3969 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 3526 | 3970 | txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC); |
|---|
| 3527 | 3971 | |
|---|
| 3528 | 3972 | if (channel <= 14) |
|---|
| 3529 | 3973 | return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER); |
|---|
| 3530 | 3974 | |
|---|
| 3531 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 3975 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 3976 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 3532 | 3977 | return clamp_t(char, txpower, MIN_A_TXPOWER_3593, |
|---|
| 3533 | 3978 | MAX_A_TXPOWER_3593); |
|---|
| 3534 | 3979 | else |
|---|
| 3535 | 3980 | return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); |
|---|
| 3981 | +} |
|---|
| 3982 | + |
|---|
| 3983 | +static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev, |
|---|
| 3984 | + struct rf_channel *rf) |
|---|
| 3985 | +{ |
|---|
| 3986 | + u8 bbp; |
|---|
| 3987 | + |
|---|
| 3988 | + bbp = (rf->channel > 14) ? 0x48 : 0x38; |
|---|
| 3989 | + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); |
|---|
| 3990 | + |
|---|
| 3991 | + rt2800_bbp_write(rt2x00dev, 69, 0x12); |
|---|
| 3992 | + |
|---|
| 3993 | + if (rf->channel <= 14) { |
|---|
| 3994 | + rt2800_bbp_write(rt2x00dev, 70, 0x0a); |
|---|
| 3995 | + } else { |
|---|
| 3996 | + /* Disable CCK packet detection */ |
|---|
| 3997 | + rt2800_bbp_write(rt2x00dev, 70, 0x00); |
|---|
| 3998 | + } |
|---|
| 3999 | + |
|---|
| 4000 | + rt2800_bbp_write(rt2x00dev, 73, 0x10); |
|---|
| 4001 | + |
|---|
| 4002 | + if (rf->channel > 14) { |
|---|
| 4003 | + rt2800_bbp_write(rt2x00dev, 62, 0x1d); |
|---|
| 4004 | + rt2800_bbp_write(rt2x00dev, 63, 0x1d); |
|---|
| 4005 | + rt2800_bbp_write(rt2x00dev, 64, 0x1d); |
|---|
| 4006 | + } else { |
|---|
| 4007 | + rt2800_bbp_write(rt2x00dev, 62, 0x2d); |
|---|
| 4008 | + rt2800_bbp_write(rt2x00dev, 63, 0x2d); |
|---|
| 4009 | + rt2800_bbp_write(rt2x00dev, 64, 0x2d); |
|---|
| 4010 | + } |
|---|
| 3536 | 4011 | } |
|---|
| 3537 | 4012 | |
|---|
| 3538 | 4013 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, |
|---|
| .. | .. |
|---|
| 3553 | 4028 | rt2800_txpower_to_dev(rt2x00dev, rf->channel, |
|---|
| 3554 | 4029 | info->default_power3); |
|---|
| 3555 | 4030 | |
|---|
| 4031 | + switch (rt2x00dev->chip.rt) { |
|---|
| 4032 | + case RT3883: |
|---|
| 4033 | + rt3883_bbp_adjust(rt2x00dev, rf); |
|---|
| 4034 | + break; |
|---|
| 4035 | + } |
|---|
| 4036 | + |
|---|
| 3556 | 4037 | switch (rt2x00dev->chip.rf) { |
|---|
| 3557 | 4038 | case RF2020: |
|---|
| 3558 | 4039 | case RF3020: |
|---|
| .. | .. |
|---|
| 3572 | 4053 | break; |
|---|
| 3573 | 4054 | case RF3322: |
|---|
| 3574 | 4055 | rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); |
|---|
| 4056 | + break; |
|---|
| 4057 | + case RF3853: |
|---|
| 4058 | + rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); |
|---|
| 3575 | 4059 | break; |
|---|
| 3576 | 4060 | case RF3070: |
|---|
| 3577 | 4061 | case RF5350: |
|---|
| .. | .. |
|---|
| 3654 | 4138 | rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); |
|---|
| 3655 | 4139 | rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); |
|---|
| 3656 | 4140 | rt2800_bbp_write(rt2x00dev, 77, 0x98); |
|---|
| 4141 | + } else if (rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 4142 | + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); |
|---|
| 4143 | + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); |
|---|
| 4144 | + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); |
|---|
| 4145 | + |
|---|
| 4146 | + if (rt2x00dev->default_ant.rx_chain_num > 1) |
|---|
| 4147 | + rt2800_bbp_write(rt2x00dev, 86, 0x46); |
|---|
| 4148 | + else |
|---|
| 4149 | + rt2800_bbp_write(rt2x00dev, 86, 0); |
|---|
| 3657 | 4150 | } else { |
|---|
| 3658 | 4151 | rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); |
|---|
| 3659 | 4152 | rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); |
|---|
| 3660 | 4153 | rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); |
|---|
| 3661 | | - rt2800_bbp_write(rt2x00dev, 86, 0); |
|---|
| 4154 | + if (rt2x00_rt(rt2x00dev, RT6352)) |
|---|
| 4155 | + rt2800_bbp_write(rt2x00dev, 86, 0x38); |
|---|
| 4156 | + else |
|---|
| 4157 | + rt2800_bbp_write(rt2x00dev, 86, 0); |
|---|
| 3662 | 4158 | } |
|---|
| 3663 | 4159 | |
|---|
| 3664 | 4160 | if (rf->channel <= 14) { |
|---|
| .. | .. |
|---|
| 3666 | 4162 | !rt2x00_rt(rt2x00dev, RT5392) && |
|---|
| 3667 | 4163 | !rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 3668 | 4164 | if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { |
|---|
| 4165 | + rt2800_bbp_write(rt2x00dev, 82, 0x62); |
|---|
| 3669 | 4166 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
|---|
| 3670 | 4167 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
|---|
| 3671 | 4168 | } else { |
|---|
| .. | .. |
|---|
| 3675 | 4172 | rt2800_bbp_write(rt2x00dev, 82, 0x84); |
|---|
| 3676 | 4173 | rt2800_bbp_write(rt2x00dev, 75, 0x50); |
|---|
| 3677 | 4174 | } |
|---|
| 3678 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 4175 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 4176 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 3679 | 4177 | rt2800_bbp_write(rt2x00dev, 83, 0x8a); |
|---|
| 3680 | 4178 | } |
|---|
| 3681 | 4179 | |
|---|
| 3682 | 4180 | } else { |
|---|
| 3683 | 4181 | if (rt2x00_rt(rt2x00dev, RT3572)) |
|---|
| 3684 | 4182 | rt2800_bbp_write(rt2x00dev, 82, 0x94); |
|---|
| 3685 | | - else if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 4183 | + else if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 4184 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 3686 | 4185 | rt2800_bbp_write(rt2x00dev, 82, 0x82); |
|---|
| 3687 | 4186 | else if (!rt2x00_rt(rt2x00dev, RT6352)) |
|---|
| 3688 | 4187 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); |
|---|
| 3689 | 4188 | |
|---|
| 3690 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 4189 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 4190 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 3691 | 4191 | rt2800_bbp_write(rt2x00dev, 83, 0x9a); |
|---|
| 3692 | 4192 | |
|---|
| 3693 | 4193 | if (rt2x00_has_cap_external_lna_a(rt2x00dev)) |
|---|
| .. | .. |
|---|
| 3705 | 4205 | if (rt2x00_rt(rt2x00dev, RT3572)) |
|---|
| 3706 | 4206 | rt2800_rfcsr_write(rt2x00dev, 8, 0); |
|---|
| 3707 | 4207 | |
|---|
| 3708 | | - if (rt2x00_rt(rt2x00dev, RT6352)) |
|---|
| 4208 | + if (rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 3709 | 4209 | tx_pin = rt2800_register_read(rt2x00dev, TX_PIN_CFG); |
|---|
| 3710 | | - else |
|---|
| 4210 | + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); |
|---|
| 4211 | + } else { |
|---|
| 3711 | 4212 | tx_pin = 0; |
|---|
| 4213 | + } |
|---|
| 3712 | 4214 | |
|---|
| 3713 | 4215 | switch (rt2x00dev->default_ant.tx_chain_num) { |
|---|
| 3714 | 4216 | case 3: |
|---|
| .. | .. |
|---|
| 3717 | 4219 | rf->channel > 14); |
|---|
| 3718 | 4220 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN, |
|---|
| 3719 | 4221 | rf->channel <= 14); |
|---|
| 3720 | | - /* fall-through */ |
|---|
| 4222 | + fallthrough; |
|---|
| 3721 | 4223 | case 2: |
|---|
| 3722 | 4224 | /* Turn on secondary PAs */ |
|---|
| 3723 | 4225 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, |
|---|
| 3724 | 4226 | rf->channel > 14); |
|---|
| 3725 | 4227 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, |
|---|
| 3726 | 4228 | rf->channel <= 14); |
|---|
| 3727 | | - /* fall-through */ |
|---|
| 4229 | + fallthrough; |
|---|
| 3728 | 4230 | case 1: |
|---|
| 3729 | 4231 | /* Turn on primary PAs */ |
|---|
| 3730 | 4232 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, |
|---|
| .. | .. |
|---|
| 3742 | 4244 | /* Turn on tertiary LNAs */ |
|---|
| 3743 | 4245 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1); |
|---|
| 3744 | 4246 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1); |
|---|
| 3745 | | - /* fall-through */ |
|---|
| 4247 | + fallthrough; |
|---|
| 3746 | 4248 | case 2: |
|---|
| 3747 | 4249 | /* Turn on secondary LNAs */ |
|---|
| 3748 | 4250 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); |
|---|
| 3749 | 4251 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); |
|---|
| 3750 | | - /* fall-through */ |
|---|
| 4252 | + fallthrough; |
|---|
| 3751 | 4253 | case 1: |
|---|
| 3752 | 4254 | /* Turn on primary LNAs */ |
|---|
| 3753 | 4255 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); |
|---|
| .. | .. |
|---|
| 3757 | 4259 | |
|---|
| 3758 | 4260 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); |
|---|
| 3759 | 4261 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); |
|---|
| 3760 | | - rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */ |
|---|
| 3761 | 4262 | |
|---|
| 3762 | 4263 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); |
|---|
| 3763 | 4264 | |
|---|
| .. | .. |
|---|
| 3816 | 4317 | usleep_range(1000, 1500); |
|---|
| 3817 | 4318 | } |
|---|
| 3818 | 4319 | |
|---|
| 4320 | + if (rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 4321 | + if (!conf_is_ht40(conf)) |
|---|
| 4322 | + rt2800_bbp_write(rt2x00dev, 105, 0x34); |
|---|
| 4323 | + else |
|---|
| 4324 | + rt2800_bbp_write(rt2x00dev, 105, 0x04); |
|---|
| 4325 | + |
|---|
| 4326 | + /* AGC init */ |
|---|
| 4327 | + if (rf->channel <= 14) |
|---|
| 4328 | + reg = 0x2e + rt2x00dev->lna_gain; |
|---|
| 4329 | + else |
|---|
| 4330 | + reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3); |
|---|
| 4331 | + |
|---|
| 4332 | + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); |
|---|
| 4333 | + |
|---|
| 4334 | + usleep_range(1000, 1500); |
|---|
| 4335 | + } |
|---|
| 4336 | + |
|---|
| 3819 | 4337 | if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 3820 | 4338 | reg = 0x10; |
|---|
| 3821 | 4339 | if (!conf_is_ht40(conf)) { |
|---|
| .. | .. |
|---|
| 3829 | 4347 | rt2800_bbp_write(rt2x00dev, 195, 141); |
|---|
| 3830 | 4348 | rt2800_bbp_write(rt2x00dev, 196, reg); |
|---|
| 3831 | 4349 | |
|---|
| 3832 | | - /* AGC init */ |
|---|
| 3833 | | - if (rt2x00_rt(rt2x00dev, RT6352)) |
|---|
| 3834 | | - reg = 0x04; |
|---|
| 3835 | | - else |
|---|
| 3836 | | - reg = rf->channel <= 14 ? 0x1c : 0x24; |
|---|
| 3837 | | - |
|---|
| 3838 | | - reg += 2 * rt2x00dev->lna_gain; |
|---|
| 4350 | + /* AGC init. |
|---|
| 4351 | + * Despite the vendor driver using different values here for |
|---|
| 4352 | + * RT6352 chip, we use 0x1c for now. This may have to be changed |
|---|
| 4353 | + * once TSSI got implemented. |
|---|
| 4354 | + */ |
|---|
| 4355 | + reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; |
|---|
| 3839 | 4356 | rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); |
|---|
| 3840 | 4357 | |
|---|
| 3841 | | - rt2800_iq_calibrate(rt2x00dev, rf->channel); |
|---|
| 4358 | + if (rt2x00_rt(rt2x00dev, RT5592)) |
|---|
| 4359 | + rt2800_iq_calibrate(rt2x00dev, rf->channel); |
|---|
| 3842 | 4360 | } |
|---|
| 3843 | 4361 | |
|---|
| 3844 | 4362 | bbp = rt2800_bbp_read(rt2x00dev, 4); |
|---|
| .. | .. |
|---|
| 4075 | 4593 | |
|---|
| 4076 | 4594 | if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 4077 | 4595 | return min_t(u8, txpower, 0xc); |
|---|
| 4596 | + |
|---|
| 4597 | + if (rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 4598 | + return min_t(u8, txpower, 0xf); |
|---|
| 4078 | 4599 | |
|---|
| 4079 | 4600 | if (rt2x00_has_cap_power_limit(rt2x00dev)) { |
|---|
| 4080 | 4601 | /* |
|---|
| .. | .. |
|---|
| 4837 | 5358 | struct ieee80211_channel *chan, |
|---|
| 4838 | 5359 | int power_level) |
|---|
| 4839 | 5360 | { |
|---|
| 4840 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 5361 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 5362 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 4841 | 5363 | rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); |
|---|
| 4842 | 5364 | else if (rt2x00_rt(rt2x00dev, RT6352)) |
|---|
| 4843 | 5365 | rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level); |
|---|
| .. | .. |
|---|
| 4884 | 5406 | case RF3053: |
|---|
| 4885 | 5407 | case RF3070: |
|---|
| 4886 | 5408 | case RF3290: |
|---|
| 5409 | + case RF3853: |
|---|
| 4887 | 5410 | case RF5350: |
|---|
| 4888 | 5411 | case RF5360: |
|---|
| 4889 | 5412 | case RF5362: |
|---|
| .. | .. |
|---|
| 4919 | 5442 | switch (rt2x00dev->default_ant.tx_chain_num) { |
|---|
| 4920 | 5443 | case 3: |
|---|
| 4921 | 5444 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN, 1); |
|---|
| 4922 | | - /* fall through */ |
|---|
| 5445 | + fallthrough; |
|---|
| 4923 | 5446 | case 2: |
|---|
| 4924 | 5447 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); |
|---|
| 4925 | | - /* fall through */ |
|---|
| 5448 | + fallthrough; |
|---|
| 4926 | 5449 | case 1: |
|---|
| 4927 | 5450 | default: |
|---|
| 4928 | 5451 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); |
|---|
| .. | .. |
|---|
| 4932 | 5455 | switch (rt2x00dev->default_ant.tx_chain_num) { |
|---|
| 4933 | 5456 | case 3: |
|---|
| 4934 | 5457 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN, 1); |
|---|
| 4935 | | - /* fall through */ |
|---|
| 5458 | + fallthrough; |
|---|
| 4936 | 5459 | case 2: |
|---|
| 4937 | 5460 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); |
|---|
| 4938 | | - /* fall through */ |
|---|
| 5461 | + fallthrough; |
|---|
| 4939 | 5462 | case 1: |
|---|
| 4940 | 5463 | default: |
|---|
| 4941 | 5464 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, 1); |
|---|
| .. | .. |
|---|
| 5084 | 5607 | else |
|---|
| 5085 | 5608 | vgc = 0x2e + rt2x00dev->lna_gain; |
|---|
| 5086 | 5609 | } else { /* 5GHZ band */ |
|---|
| 5087 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 5610 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 5611 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 5088 | 5612 | vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; |
|---|
| 5089 | 5613 | else if (rt2x00_rt(rt2x00dev, RT5592)) |
|---|
| 5090 | 5614 | vgc = 0x24 + (2 * rt2x00dev->lna_gain); |
|---|
| .. | .. |
|---|
| 5104 | 5628 | { |
|---|
| 5105 | 5629 | if (qual->vgc_level != vgc_level) { |
|---|
| 5106 | 5630 | if (rt2x00_rt(rt2x00dev, RT3572) || |
|---|
| 5107 | | - rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 5631 | + rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 5632 | + rt2x00_rt(rt2x00dev, RT3883) || |
|---|
| 5633 | + rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 5108 | 5634 | rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, |
|---|
| 5109 | 5635 | vgc_level); |
|---|
| 5110 | 5636 | } else if (rt2x00_rt(rt2x00dev, RT5592)) { |
|---|
| .. | .. |
|---|
| 5149 | 5675 | else |
|---|
| 5150 | 5676 | vgc += 0x10; |
|---|
| 5151 | 5677 | } |
|---|
| 5678 | + break; |
|---|
| 5679 | + |
|---|
| 5680 | + case RT3883: |
|---|
| 5681 | + if (qual->rssi > -65) |
|---|
| 5682 | + vgc += 0x10; |
|---|
| 5152 | 5683 | break; |
|---|
| 5153 | 5684 | |
|---|
| 5154 | 5685 | case RT5592: |
|---|
| .. | .. |
|---|
| 5303 | 5834 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, |
|---|
| 5304 | 5835 | 0x00000000); |
|---|
| 5305 | 5836 | } |
|---|
| 5837 | + } else if (rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 5838 | + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); |
|---|
| 5839 | + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); |
|---|
| 5840 | + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); |
|---|
| 5841 | + rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); |
|---|
| 5842 | + rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); |
|---|
| 5306 | 5843 | } else if (rt2x00_rt(rt2x00dev, RT5390) || |
|---|
| 5307 | | - rt2x00_rt(rt2x00dev, RT5392) || |
|---|
| 5308 | | - rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 5844 | + rt2x00_rt(rt2x00dev, RT5392)) { |
|---|
| 5309 | 5845 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); |
|---|
| 5310 | 5846 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
|---|
| 5311 | 5847 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); |
|---|
| .. | .. |
|---|
| 5317 | 5853 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); |
|---|
| 5318 | 5854 | } else if (rt2x00_rt(rt2x00dev, RT6352)) { |
|---|
| 5319 | 5855 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); |
|---|
| 5320 | | - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); |
|---|
| 5856 | + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); |
|---|
| 5321 | 5857 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); |
|---|
| 5322 | | - rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002); |
|---|
| 5323 | | - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F); |
|---|
| 5324 | | - rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606); |
|---|
| 5858 | + rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); |
|---|
| 5325 | 5859 | rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); |
|---|
| 5326 | 5860 | rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); |
|---|
| 5327 | 5861 | rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); |
|---|
| .. | .. |
|---|
| 5516 | 6050 | reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; |
|---|
| 5517 | 6051 | rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); |
|---|
| 5518 | 6052 | |
|---|
| 6053 | + if (rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 6054 | + rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008); |
|---|
| 6055 | + rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413); |
|---|
| 6056 | + } |
|---|
| 6057 | + |
|---|
| 5519 | 6058 | reg = rt2800_register_read(rt2x00dev, TX_RTS_CFG); |
|---|
| 5520 | 6059 | rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7); |
|---|
| 5521 | 6060 | rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, |
|---|
| .. | .. |
|---|
| 5546 | 6085 | * ASIC will keep garbage value after boot, clear encryption keys. |
|---|
| 5547 | 6086 | */ |
|---|
| 5548 | 6087 | for (i = 0; i < 4; i++) |
|---|
| 5549 | | - rt2800_register_write(rt2x00dev, |
|---|
| 5550 | | - SHARED_KEY_MODE_ENTRY(i), 0); |
|---|
| 6088 | + rt2800_register_write(rt2x00dev, SHARED_KEY_MODE_ENTRY(i), 0); |
|---|
| 5551 | 6089 | |
|---|
| 5552 | 6090 | for (i = 0; i < 256; i++) { |
|---|
| 5553 | 6091 | rt2800_config_wcid(rt2x00dev, NULL, i); |
|---|
| 5554 | 6092 | rt2800_delete_wcid_attr(rt2x00dev, i); |
|---|
| 5555 | | - rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); |
|---|
| 5556 | 6093 | } |
|---|
| 6094 | + |
|---|
| 6095 | + /* |
|---|
| 6096 | + * Clear encryption initialization vectors on start, but keep them |
|---|
| 6097 | + * for watchdog reset. Otherwise we will have wrong IVs and not be |
|---|
| 6098 | + * able to keep connections after reset. |
|---|
| 6099 | + */ |
|---|
| 6100 | + if (!test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags)) |
|---|
| 6101 | + for (i = 0; i < 256; i++) |
|---|
| 6102 | + rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); |
|---|
| 5557 | 6103 | |
|---|
| 5558 | 6104 | /* |
|---|
| 5559 | 6105 | * Clear all beacons |
|---|
| .. | .. |
|---|
| 5568 | 6114 | } else if (rt2x00_is_pcie(rt2x00dev)) { |
|---|
| 5569 | 6115 | reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); |
|---|
| 5570 | 6116 | rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125); |
|---|
| 6117 | + rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); |
|---|
| 6118 | + } else if (rt2x00_is_soc(rt2x00dev)) { |
|---|
| 6119 | + struct clk *clk = clk_get_sys("bus", NULL); |
|---|
| 6120 | + int rate; |
|---|
| 6121 | + |
|---|
| 6122 | + if (IS_ERR(clk)) { |
|---|
| 6123 | + clk = clk_get_sys("cpu", NULL); |
|---|
| 6124 | + |
|---|
| 6125 | + if (IS_ERR(clk)) { |
|---|
| 6126 | + rate = 125; |
|---|
| 6127 | + } else { |
|---|
| 6128 | + rate = clk_get_rate(clk) / 3000000; |
|---|
| 6129 | + clk_put(clk); |
|---|
| 6130 | + } |
|---|
| 6131 | + } else { |
|---|
| 6132 | + rate = clk_get_rate(clk) / 1000000; |
|---|
| 6133 | + clk_put(clk); |
|---|
| 6134 | + } |
|---|
| 6135 | + |
|---|
| 6136 | + reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); |
|---|
| 6137 | + rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, rate); |
|---|
| 5571 | 6138 | rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); |
|---|
| 5572 | 6139 | } |
|---|
| 5573 | 6140 | |
|---|
| .. | .. |
|---|
| 6132 | 6699 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
|---|
| 6133 | 6700 | } |
|---|
| 6134 | 6701 | |
|---|
| 6702 | +static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev) |
|---|
| 6703 | +{ |
|---|
| 6704 | + rt2800_init_bbp_early(rt2x00dev); |
|---|
| 6705 | + |
|---|
| 6706 | + rt2800_bbp_write(rt2x00dev, 4, 0x50); |
|---|
| 6707 | + rt2800_bbp_write(rt2x00dev, 47, 0x48); |
|---|
| 6708 | + |
|---|
| 6709 | + rt2800_bbp_write(rt2x00dev, 86, 0x46); |
|---|
| 6710 | + rt2800_bbp_write(rt2x00dev, 88, 0x90); |
|---|
| 6711 | + |
|---|
| 6712 | + rt2800_bbp_write(rt2x00dev, 92, 0x02); |
|---|
| 6713 | + |
|---|
| 6714 | + rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
|---|
| 6715 | + rt2800_bbp_write(rt2x00dev, 104, 0x92); |
|---|
| 6716 | + rt2800_bbp_write(rt2x00dev, 105, 0x34); |
|---|
| 6717 | + rt2800_bbp_write(rt2x00dev, 106, 0x12); |
|---|
| 6718 | + rt2800_bbp_write(rt2x00dev, 120, 0x50); |
|---|
| 6719 | + rt2800_bbp_write(rt2x00dev, 137, 0x0f); |
|---|
| 6720 | + rt2800_bbp_write(rt2x00dev, 163, 0x9d); |
|---|
| 6721 | + |
|---|
| 6722 | + /* Set ITxBF timeout to 0x9C40=1000msec */ |
|---|
| 6723 | + rt2800_bbp_write(rt2x00dev, 179, 0x02); |
|---|
| 6724 | + rt2800_bbp_write(rt2x00dev, 180, 0x00); |
|---|
| 6725 | + rt2800_bbp_write(rt2x00dev, 182, 0x40); |
|---|
| 6726 | + rt2800_bbp_write(rt2x00dev, 180, 0x01); |
|---|
| 6727 | + rt2800_bbp_write(rt2x00dev, 182, 0x9c); |
|---|
| 6728 | + |
|---|
| 6729 | + rt2800_bbp_write(rt2x00dev, 179, 0x00); |
|---|
| 6730 | + |
|---|
| 6731 | + /* Reprogram the inband interface to put right values in RXWI */ |
|---|
| 6732 | + rt2800_bbp_write(rt2x00dev, 142, 0x04); |
|---|
| 6733 | + rt2800_bbp_write(rt2x00dev, 143, 0x3b); |
|---|
| 6734 | + rt2800_bbp_write(rt2x00dev, 142, 0x06); |
|---|
| 6735 | + rt2800_bbp_write(rt2x00dev, 143, 0xa0); |
|---|
| 6736 | + rt2800_bbp_write(rt2x00dev, 142, 0x07); |
|---|
| 6737 | + rt2800_bbp_write(rt2x00dev, 143, 0xa1); |
|---|
| 6738 | + rt2800_bbp_write(rt2x00dev, 142, 0x08); |
|---|
| 6739 | + rt2800_bbp_write(rt2x00dev, 143, 0xa2); |
|---|
| 6740 | + rt2800_bbp_write(rt2x00dev, 148, 0xc8); |
|---|
| 6741 | +} |
|---|
| 6742 | + |
|---|
| 6135 | 6743 | static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) |
|---|
| 6136 | 6744 | { |
|---|
| 6137 | 6745 | int ant, div_mode; |
|---|
| .. | .. |
|---|
| 6575 | 7183 | break; |
|---|
| 6576 | 7184 | case RT3593: |
|---|
| 6577 | 7185 | rt2800_init_bbp_3593(rt2x00dev); |
|---|
| 7186 | + return; |
|---|
| 7187 | + case RT3883: |
|---|
| 7188 | + rt2800_init_bbp_3883(rt2x00dev); |
|---|
| 6578 | 7189 | return; |
|---|
| 6579 | 7190 | case RT5390: |
|---|
| 6580 | 7191 | case RT5392: |
|---|
| .. | .. |
|---|
| 7447 | 8058 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); |
|---|
| 7448 | 8059 | } |
|---|
| 7449 | 8060 | |
|---|
| 8061 | +static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev) |
|---|
| 8062 | +{ |
|---|
| 8063 | + u8 rfcsr; |
|---|
| 8064 | + |
|---|
| 8065 | + /* TODO: get the actual ECO value from the SoC */ |
|---|
| 8066 | + const unsigned int eco = 5; |
|---|
| 8067 | + |
|---|
| 8068 | + rt2800_rf_init_calibration(rt2x00dev, 2); |
|---|
| 8069 | + |
|---|
| 8070 | + rt2800_rfcsr_write(rt2x00dev, 0, 0xe0); |
|---|
| 8071 | + rt2800_rfcsr_write(rt2x00dev, 1, 0x03); |
|---|
| 8072 | + rt2800_rfcsr_write(rt2x00dev, 2, 0x50); |
|---|
| 8073 | + rt2800_rfcsr_write(rt2x00dev, 3, 0x20); |
|---|
| 8074 | + rt2800_rfcsr_write(rt2x00dev, 4, 0x00); |
|---|
| 8075 | + rt2800_rfcsr_write(rt2x00dev, 5, 0x00); |
|---|
| 8076 | + rt2800_rfcsr_write(rt2x00dev, 6, 0x40); |
|---|
| 8077 | + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); |
|---|
| 8078 | + rt2800_rfcsr_write(rt2x00dev, 8, 0x5b); |
|---|
| 8079 | + rt2800_rfcsr_write(rt2x00dev, 9, 0x08); |
|---|
| 8080 | + rt2800_rfcsr_write(rt2x00dev, 10, 0xd3); |
|---|
| 8081 | + rt2800_rfcsr_write(rt2x00dev, 11, 0x48); |
|---|
| 8082 | + rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); |
|---|
| 8083 | + rt2800_rfcsr_write(rt2x00dev, 13, 0x12); |
|---|
| 8084 | + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); |
|---|
| 8085 | + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); |
|---|
| 8086 | + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); |
|---|
| 8087 | + |
|---|
| 8088 | + /* RFCSR 17 will be initialized later based on the |
|---|
| 8089 | + * frequency offset stored in the EEPROM |
|---|
| 8090 | + */ |
|---|
| 8091 | + |
|---|
| 8092 | + rt2800_rfcsr_write(rt2x00dev, 18, 0x40); |
|---|
| 8093 | + rt2800_rfcsr_write(rt2x00dev, 19, 0x00); |
|---|
| 8094 | + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); |
|---|
| 8095 | + rt2800_rfcsr_write(rt2x00dev, 21, 0x00); |
|---|
| 8096 | + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); |
|---|
| 8097 | + rt2800_rfcsr_write(rt2x00dev, 23, 0xc0); |
|---|
| 8098 | + rt2800_rfcsr_write(rt2x00dev, 24, 0x00); |
|---|
| 8099 | + rt2800_rfcsr_write(rt2x00dev, 25, 0x00); |
|---|
| 8100 | + rt2800_rfcsr_write(rt2x00dev, 26, 0x00); |
|---|
| 8101 | + rt2800_rfcsr_write(rt2x00dev, 27, 0x00); |
|---|
| 8102 | + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); |
|---|
| 8103 | + rt2800_rfcsr_write(rt2x00dev, 29, 0x00); |
|---|
| 8104 | + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); |
|---|
| 8105 | + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); |
|---|
| 8106 | + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); |
|---|
| 8107 | + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); |
|---|
| 8108 | + rt2800_rfcsr_write(rt2x00dev, 34, 0x20); |
|---|
| 8109 | + rt2800_rfcsr_write(rt2x00dev, 35, 0x00); |
|---|
| 8110 | + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); |
|---|
| 8111 | + rt2800_rfcsr_write(rt2x00dev, 37, 0x00); |
|---|
| 8112 | + rt2800_rfcsr_write(rt2x00dev, 38, 0x86); |
|---|
| 8113 | + rt2800_rfcsr_write(rt2x00dev, 39, 0x23); |
|---|
| 8114 | + rt2800_rfcsr_write(rt2x00dev, 40, 0x00); |
|---|
| 8115 | + rt2800_rfcsr_write(rt2x00dev, 41, 0x00); |
|---|
| 8116 | + rt2800_rfcsr_write(rt2x00dev, 42, 0x00); |
|---|
| 8117 | + rt2800_rfcsr_write(rt2x00dev, 43, 0x00); |
|---|
| 8118 | + rt2800_rfcsr_write(rt2x00dev, 44, 0x93); |
|---|
| 8119 | + rt2800_rfcsr_write(rt2x00dev, 45, 0xbb); |
|---|
| 8120 | + rt2800_rfcsr_write(rt2x00dev, 46, 0x60); |
|---|
| 8121 | + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); |
|---|
| 8122 | + rt2800_rfcsr_write(rt2x00dev, 48, 0x00); |
|---|
| 8123 | + rt2800_rfcsr_write(rt2x00dev, 49, 0x8e); |
|---|
| 8124 | + rt2800_rfcsr_write(rt2x00dev, 50, 0x86); |
|---|
| 8125 | + rt2800_rfcsr_write(rt2x00dev, 51, 0x51); |
|---|
| 8126 | + rt2800_rfcsr_write(rt2x00dev, 52, 0x05); |
|---|
| 8127 | + rt2800_rfcsr_write(rt2x00dev, 53, 0x76); |
|---|
| 8128 | + rt2800_rfcsr_write(rt2x00dev, 54, 0x76); |
|---|
| 8129 | + rt2800_rfcsr_write(rt2x00dev, 55, 0x76); |
|---|
| 8130 | + rt2800_rfcsr_write(rt2x00dev, 56, 0xdb); |
|---|
| 8131 | + rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); |
|---|
| 8132 | + rt2800_rfcsr_write(rt2x00dev, 58, 0x00); |
|---|
| 8133 | + rt2800_rfcsr_write(rt2x00dev, 59, 0x00); |
|---|
| 8134 | + rt2800_rfcsr_write(rt2x00dev, 60, 0x00); |
|---|
| 8135 | + rt2800_rfcsr_write(rt2x00dev, 61, 0x00); |
|---|
| 8136 | + rt2800_rfcsr_write(rt2x00dev, 62, 0x00); |
|---|
| 8137 | + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); |
|---|
| 8138 | + |
|---|
| 8139 | + /* TODO: rx filter calibration? */ |
|---|
| 8140 | + |
|---|
| 8141 | + rt2800_bbp_write(rt2x00dev, 137, 0x0f); |
|---|
| 8142 | + |
|---|
| 8143 | + rt2800_bbp_write(rt2x00dev, 163, 0x9d); |
|---|
| 8144 | + |
|---|
| 8145 | + rt2800_bbp_write(rt2x00dev, 105, 0x05); |
|---|
| 8146 | + |
|---|
| 8147 | + rt2800_bbp_write(rt2x00dev, 179, 0x02); |
|---|
| 8148 | + rt2800_bbp_write(rt2x00dev, 180, 0x00); |
|---|
| 8149 | + rt2800_bbp_write(rt2x00dev, 182, 0x40); |
|---|
| 8150 | + rt2800_bbp_write(rt2x00dev, 180, 0x01); |
|---|
| 8151 | + rt2800_bbp_write(rt2x00dev, 182, 0x9c); |
|---|
| 8152 | + |
|---|
| 8153 | + rt2800_bbp_write(rt2x00dev, 179, 0x00); |
|---|
| 8154 | + |
|---|
| 8155 | + rt2800_bbp_write(rt2x00dev, 142, 0x04); |
|---|
| 8156 | + rt2800_bbp_write(rt2x00dev, 143, 0x3b); |
|---|
| 8157 | + rt2800_bbp_write(rt2x00dev, 142, 0x06); |
|---|
| 8158 | + rt2800_bbp_write(rt2x00dev, 143, 0xa0); |
|---|
| 8159 | + rt2800_bbp_write(rt2x00dev, 142, 0x07); |
|---|
| 8160 | + rt2800_bbp_write(rt2x00dev, 143, 0xa1); |
|---|
| 8161 | + rt2800_bbp_write(rt2x00dev, 142, 0x08); |
|---|
| 8162 | + rt2800_bbp_write(rt2x00dev, 143, 0xa2); |
|---|
| 8163 | + rt2800_bbp_write(rt2x00dev, 148, 0xc8); |
|---|
| 8164 | + |
|---|
| 8165 | + if (eco == 5) { |
|---|
| 8166 | + rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); |
|---|
| 8167 | + rt2800_rfcsr_write(rt2x00dev, 33, 0x32); |
|---|
| 8168 | + } |
|---|
| 8169 | + |
|---|
| 8170 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 2); |
|---|
| 8171 | + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0); |
|---|
| 8172 | + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); |
|---|
| 8173 | + rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); |
|---|
| 8174 | + msleep(1); |
|---|
| 8175 | + rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); |
|---|
| 8176 | + rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); |
|---|
| 8177 | + |
|---|
| 8178 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); |
|---|
| 8179 | + rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); |
|---|
| 8180 | + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); |
|---|
| 8181 | + |
|---|
| 8182 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 6); |
|---|
| 8183 | + rfcsr |= 0xc0; |
|---|
| 8184 | + rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); |
|---|
| 8185 | + |
|---|
| 8186 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 22); |
|---|
| 8187 | + rfcsr |= 0x20; |
|---|
| 8188 | + rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); |
|---|
| 8189 | + |
|---|
| 8190 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 46); |
|---|
| 8191 | + rfcsr |= 0x20; |
|---|
| 8192 | + rt2800_rfcsr_write(rt2x00dev, 46, rfcsr); |
|---|
| 8193 | + |
|---|
| 8194 | + rfcsr = rt2800_rfcsr_read(rt2x00dev, 20); |
|---|
| 8195 | + rfcsr &= ~0xee; |
|---|
| 8196 | + rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); |
|---|
| 8197 | +} |
|---|
| 8198 | + |
|---|
| 7450 | 8199 | static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) |
|---|
| 7451 | 8200 | { |
|---|
| 7452 | 8201 | rt2800_rf_init_calibration(rt2x00dev, 2); |
|---|
| .. | .. |
|---|
| 8289 | 9038 | case RT3390: |
|---|
| 8290 | 9039 | rt2800_init_rfcsr_3390(rt2x00dev); |
|---|
| 8291 | 9040 | break; |
|---|
| 9041 | + case RT3883: |
|---|
| 9042 | + rt2800_init_rfcsr_3883(rt2x00dev); |
|---|
| 9043 | + break; |
|---|
| 8292 | 9044 | case RT3572: |
|---|
| 8293 | 9045 | rt2800_init_rfcsr_3572(rt2x00dev); |
|---|
| 8294 | 9046 | break; |
|---|
| .. | .. |
|---|
| 8494 | 9246 | { |
|---|
| 8495 | 9247 | u16 word; |
|---|
| 8496 | 9248 | |
|---|
| 8497 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 9249 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 9250 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 8498 | 9251 | return 0; |
|---|
| 8499 | 9252 | |
|---|
| 8500 | 9253 | word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG); |
|---|
| .. | .. |
|---|
| 8508 | 9261 | { |
|---|
| 8509 | 9262 | u16 word; |
|---|
| 8510 | 9263 | |
|---|
| 8511 | | - if (rt2x00_rt(rt2x00dev, RT3593)) |
|---|
| 9264 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 9265 | + rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 8512 | 9266 | return 0; |
|---|
| 8513 | 9267 | |
|---|
| 8514 | 9268 | word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A); |
|---|
| .. | .. |
|---|
| 8614 | 9368 | word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2); |
|---|
| 8615 | 9369 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) |
|---|
| 8616 | 9370 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); |
|---|
| 8617 | | - if (!rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 9371 | + if (!rt2x00_rt(rt2x00dev, RT3593) && |
|---|
| 9372 | + !rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 8618 | 9373 | if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || |
|---|
| 8619 | 9374 | rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) |
|---|
| 8620 | 9375 | rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, |
|---|
| .. | .. |
|---|
| 8634 | 9389 | word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2); |
|---|
| 8635 | 9390 | if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) |
|---|
| 8636 | 9391 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); |
|---|
| 8637 | | - if (!rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 9392 | + if (!rt2x00_rt(rt2x00dev, RT3593) && |
|---|
| 9393 | + !rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 8638 | 9394 | if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || |
|---|
| 8639 | 9395 | rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) |
|---|
| 8640 | 9396 | rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, |
|---|
| .. | .. |
|---|
| 8642 | 9398 | } |
|---|
| 8643 | 9399 | rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); |
|---|
| 8644 | 9400 | |
|---|
| 8645 | | - if (rt2x00_rt(rt2x00dev, RT3593)) { |
|---|
| 9401 | + if (rt2x00_rt(rt2x00dev, RT3593) || |
|---|
| 9402 | + rt2x00_rt(rt2x00dev, RT3883)) { |
|---|
| 8646 | 9403 | word = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); |
|---|
| 8647 | 9404 | if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 || |
|---|
| 8648 | 9405 | rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) |
|---|
| .. | .. |
|---|
| 8681 | 9438 | rf = rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID); |
|---|
| 8682 | 9439 | else if (rt2x00_rt(rt2x00dev, RT3352)) |
|---|
| 8683 | 9440 | rf = RF3322; |
|---|
| 9441 | + else if (rt2x00_rt(rt2x00dev, RT3883)) |
|---|
| 9442 | + rf = RF3853; |
|---|
| 8684 | 9443 | else if (rt2x00_rt(rt2x00dev, RT5350)) |
|---|
| 8685 | 9444 | rf = RF5350; |
|---|
| 8686 | 9445 | else |
|---|
| .. | .. |
|---|
| 8701 | 9460 | case RF3290: |
|---|
| 8702 | 9461 | case RF3320: |
|---|
| 8703 | 9462 | case RF3322: |
|---|
| 9463 | + case RF3853: |
|---|
| 8704 | 9464 | case RF5350: |
|---|
| 8705 | 9465 | case RF5360: |
|---|
| 8706 | 9466 | case RF5362: |
|---|
| .. | .. |
|---|
| 8987 | 9747 | {14, 0xF0, 2, 0x18}, |
|---|
| 8988 | 9748 | }; |
|---|
| 8989 | 9749 | |
|---|
| 9750 | +static const struct rf_channel rf_vals_3853[] = { |
|---|
| 9751 | + {1, 241, 6, 2}, |
|---|
| 9752 | + {2, 241, 6, 7}, |
|---|
| 9753 | + {3, 242, 6, 2}, |
|---|
| 9754 | + {4, 242, 6, 7}, |
|---|
| 9755 | + {5, 243, 6, 2}, |
|---|
| 9756 | + {6, 243, 6, 7}, |
|---|
| 9757 | + {7, 244, 6, 2}, |
|---|
| 9758 | + {8, 244, 6, 7}, |
|---|
| 9759 | + {9, 245, 6, 2}, |
|---|
| 9760 | + {10, 245, 6, 7}, |
|---|
| 9761 | + {11, 246, 6, 2}, |
|---|
| 9762 | + {12, 246, 6, 7}, |
|---|
| 9763 | + {13, 247, 6, 2}, |
|---|
| 9764 | + {14, 248, 6, 4}, |
|---|
| 9765 | + |
|---|
| 9766 | + {36, 0x56, 8, 4}, |
|---|
| 9767 | + {38, 0x56, 8, 6}, |
|---|
| 9768 | + {40, 0x56, 8, 8}, |
|---|
| 9769 | + {44, 0x57, 8, 0}, |
|---|
| 9770 | + {46, 0x57, 8, 2}, |
|---|
| 9771 | + {48, 0x57, 8, 4}, |
|---|
| 9772 | + {52, 0x57, 8, 8}, |
|---|
| 9773 | + {54, 0x57, 8, 10}, |
|---|
| 9774 | + {56, 0x58, 8, 0}, |
|---|
| 9775 | + {60, 0x58, 8, 4}, |
|---|
| 9776 | + {62, 0x58, 8, 6}, |
|---|
| 9777 | + {64, 0x58, 8, 8}, |
|---|
| 9778 | + |
|---|
| 9779 | + {100, 0x5b, 8, 8}, |
|---|
| 9780 | + {102, 0x5b, 8, 10}, |
|---|
| 9781 | + {104, 0x5c, 8, 0}, |
|---|
| 9782 | + {108, 0x5c, 8, 4}, |
|---|
| 9783 | + {110, 0x5c, 8, 6}, |
|---|
| 9784 | + {112, 0x5c, 8, 8}, |
|---|
| 9785 | + {114, 0x5c, 8, 10}, |
|---|
| 9786 | + {116, 0x5d, 8, 0}, |
|---|
| 9787 | + {118, 0x5d, 8, 2}, |
|---|
| 9788 | + {120, 0x5d, 8, 4}, |
|---|
| 9789 | + {124, 0x5d, 8, 8}, |
|---|
| 9790 | + {126, 0x5d, 8, 10}, |
|---|
| 9791 | + {128, 0x5e, 8, 0}, |
|---|
| 9792 | + {132, 0x5e, 8, 4}, |
|---|
| 9793 | + {134, 0x5e, 8, 6}, |
|---|
| 9794 | + {136, 0x5e, 8, 8}, |
|---|
| 9795 | + {140, 0x5f, 8, 0}, |
|---|
| 9796 | + |
|---|
| 9797 | + {149, 0x5f, 8, 9}, |
|---|
| 9798 | + {151, 0x5f, 8, 11}, |
|---|
| 9799 | + {153, 0x60, 8, 1}, |
|---|
| 9800 | + {157, 0x60, 8, 5}, |
|---|
| 9801 | + {159, 0x60, 8, 7}, |
|---|
| 9802 | + {161, 0x60, 8, 9}, |
|---|
| 9803 | + {165, 0x61, 8, 1}, |
|---|
| 9804 | + {167, 0x61, 8, 3}, |
|---|
| 9805 | + {169, 0x61, 8, 5}, |
|---|
| 9806 | + {171, 0x61, 8, 7}, |
|---|
| 9807 | + {173, 0x61, 8, 9}, |
|---|
| 9808 | +}; |
|---|
| 9809 | + |
|---|
| 8990 | 9810 | static const struct rf_channel rf_vals_5592_xtal20[] = { |
|---|
| 8991 | 9811 | /* Channel, N, K, mod, R */ |
|---|
| 8992 | 9812 | {1, 482, 4, 10, 3}, |
|---|
| .. | .. |
|---|
| 9177 | 9997 | if (!rt2x00_is_usb(rt2x00dev)) |
|---|
| 9178 | 9998 | ieee80211_hw_set(rt2x00dev->hw, HOST_BROADCAST_PS_BUFFERING); |
|---|
| 9179 | 9999 | |
|---|
| 9180 | | - /* Set MFP if HW crypto is disabled. */ |
|---|
| 9181 | | - if (rt2800_hwcrypt_disabled(rt2x00dev)) |
|---|
| 9182 | | - ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE); |
|---|
| 10000 | + ieee80211_hw_set(rt2x00dev->hw, MFP_CAPABLE); |
|---|
| 9183 | 10001 | |
|---|
| 9184 | 10002 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
|---|
| 9185 | 10003 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
|---|
| .. | .. |
|---|
| 9250 | 10068 | spec->channels = rf_vals_3x; |
|---|
| 9251 | 10069 | break; |
|---|
| 9252 | 10070 | |
|---|
| 10071 | + case RF3853: |
|---|
| 10072 | + spec->num_channels = ARRAY_SIZE(rf_vals_3853); |
|---|
| 10073 | + spec->channels = rf_vals_3853; |
|---|
| 10074 | + break; |
|---|
| 10075 | + |
|---|
| 9253 | 10076 | case RF5592: |
|---|
| 9254 | 10077 | reg = rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX); |
|---|
| 9255 | 10078 | if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { |
|---|
| .. | .. |
|---|
| 9303 | 10126 | switch (rx_chains) { |
|---|
| 9304 | 10127 | case 3: |
|---|
| 9305 | 10128 | spec->ht.mcs.rx_mask[2] = 0xff; |
|---|
| 10129 | + fallthrough; |
|---|
| 9306 | 10130 | case 2: |
|---|
| 9307 | 10131 | spec->ht.mcs.rx_mask[1] = 0xff; |
|---|
| 10132 | + fallthrough; |
|---|
| 9308 | 10133 | case 1: |
|---|
| 9309 | 10134 | spec->ht.mcs.rx_mask[0] = 0xff; |
|---|
| 9310 | 10135 | spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */ |
|---|
| .. | .. |
|---|
| 9367 | 10192 | case RF3053: |
|---|
| 9368 | 10193 | case RF3070: |
|---|
| 9369 | 10194 | case RF3290: |
|---|
| 10195 | + case RF3853: |
|---|
| 9370 | 10196 | case RF5350: |
|---|
| 9371 | 10197 | case RF5360: |
|---|
| 9372 | 10198 | case RF5362: |
|---|
| .. | .. |
|---|
| 9409 | 10235 | case RT3390: |
|---|
| 9410 | 10236 | case RT3572: |
|---|
| 9411 | 10237 | case RT3593: |
|---|
| 10238 | + case RT3883: |
|---|
| 9412 | 10239 | case RT5350: |
|---|
| 9413 | 10240 | case RT5390: |
|---|
| 9414 | 10241 | case RT5392: |
|---|
| .. | .. |
|---|
| 9487 | 10314 | else { |
|---|
| 9488 | 10315 | __set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags); |
|---|
| 9489 | 10316 | __set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags); |
|---|
| 10317 | + } |
|---|
| 10318 | + |
|---|
| 10319 | + if (modparam_watchdog) { |
|---|
| 10320 | + __set_bit(CAPABILITY_RESTART_HW, &rt2x00dev->cap_flags); |
|---|
| 10321 | + rt2x00dev->link.watchdog_interval = msecs_to_jiffies(100); |
|---|
| 10322 | + } else { |
|---|
| 10323 | + rt2x00dev->link.watchdog_disabled = true; |
|---|
| 9490 | 10324 | } |
|---|
| 9491 | 10325 | |
|---|
| 9492 | 10326 | /* |
|---|
| .. | .. |
|---|
| 9660 | 10494 | * when the hw reorders frames due to aggregation. |
|---|
| 9661 | 10495 | */ |
|---|
| 9662 | 10496 | if (sta_priv->wcid > WCID_END) |
|---|
| 9663 | | - return 1; |
|---|
| 10497 | + return -ENOSPC; |
|---|
| 9664 | 10498 | |
|---|
| 9665 | 10499 | switch (action) { |
|---|
| 9666 | 10500 | case IEEE80211_AMPDU_RX_START: |
|---|
| .. | .. |
|---|
| 9673 | 10507 | */ |
|---|
| 9674 | 10508 | break; |
|---|
| 9675 | 10509 | case IEEE80211_AMPDU_TX_START: |
|---|
| 9676 | | - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
|---|
| 10510 | + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; |
|---|
| 9677 | 10511 | break; |
|---|
| 9678 | 10512 | case IEEE80211_AMPDU_TX_STOP_CONT: |
|---|
| 9679 | 10513 | case IEEE80211_AMPDU_TX_STOP_FLUSH: |
|---|