Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'wireless-next-2025-11-27' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Johannes Berg says:

====================
Apart from the usual small things just driver updates:
- mt76:
- WED support for >32-bit DMA
- airoha NPU support
- regdomain improvements
- continued WiFi7/MLO work
- rtw89
- support USB devices RTL8852AU and RTL8852CU
- initial work for RTL8922DE
- improved injection support
- rtl8xxxu: 40 MHz connection fixes/support
- brcmfmac: Acer A1 840 tablet quirk

* tag 'wireless-next-2025-11-27' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (152 commits)
wifi: mac80211: allow sharing identical chanctx for S1G interfaces
wifi: nl80211: vendor-cmd: intel: fix a blank kernel-doc line warning
wifi: cfg80211: include s1g_primary_2mhz when comparing chandefs
wifi: cfg80211: include s1g_primary_2mhz when sending chandef
wifi: ieee80211: correct FILS status codes
mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add()
wifi: mt76: mt792x: fix wifi init fail by setting MCU_RUNNING after CLC load
wifi: mt76: Strip whitespace from build ddate
wifi: mt76: mt7996: Add missing locking in mt7996_mac_sta_rc_work()
wifi: mt76: mt7996: skip ieee80211_iter_keys() on scanning link remove
wifi: mt76: mt7996: skip deflink accounting for offchannel links
wifi: mt76: Move mt76_abort_scan out of mt76_reset_device()
wifi: mt76: mt7996: move mt7996_update_beacons under mt76 mutex
wifi: mt76: mt7996: grab mt76 mutex in mt7996_mac_sta_event()
wifi: mt76: mt7925: ensure the 6GHz A-MPDU density cap from the hardware.
wifi: mt76: mt7996: fix EMI rings for RRO
wifi: mt76: mt7996: fix using wrong phy to start in mt7996_mac_restart()
wifi: mt76: mt7996: fix MLO set key and group key issues
wifi: mt76: mt7996: fix MLD group index assignment
wifi: mt76: mt7996: use correct link_id when filling TXD and TXP
...
====================

Link: https://patch.msgid.link/20251127103806.17776-3-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+5050 -1792
+66
Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
··· 151 151 - ETSI 152 152 - JP 153 153 154 + country: 155 + $ref: /schemas/types.yaml#/definitions/string 156 + pattern: '^[A-Z]{2}$' 157 + description: 158 + ISO 3166-1 alpha-2 country code for power limits 159 + 154 160 patternProperties: 155 161 "^txpower-[256]g$": 156 162 type: object ··· 215 209 items: 216 210 minItems: 13 217 211 maxItems: 13 212 + 213 + paths-cck: 214 + $ref: /schemas/types.yaml#/definitions/uint8-array 215 + minItems: 4 216 + maxItems: 4 217 + description: 218 + 4 half-dBm backoff values (1 - 4 antennas, single spacial 219 + stream) 220 + 221 + paths-ofdm: 222 + $ref: /schemas/types.yaml#/definitions/uint8-array 223 + minItems: 4 224 + maxItems: 4 225 + description: 226 + 4 half-dBm backoff values (1 - 4 antennas, single spacial 227 + stream) 228 + 229 + paths-ofdm-bf: 230 + $ref: /schemas/types.yaml#/definitions/uint8-array 231 + minItems: 4 232 + maxItems: 4 233 + description: 234 + 4 half-dBm backoff values for beamforming 235 + (1 - 4 antennas, single spacial stream) 236 + 237 + paths-ru: 238 + $ref: /schemas/types.yaml#/definitions/uint8-matrix 239 + description: 240 + Sets of half-dBm backoff values for 802.11ax rates for 241 + 1T1ss (aka 1 transmitting antenna with 1 spacial stream), 242 + 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss, 4T2ss, 3T3ss, 4T3ss 243 + and 4T4ss. 244 + Each set starts with the number of channel bandwidth or 245 + resource unit settings for which the rate set applies, 246 + followed by 10 power limit values. The order of the 247 + channel resource unit settings is RU26, RU52, RU106, 248 + RU242/SU20, RU484/SU40, RU996/SU80 and RU2x996/SU160. 249 + minItems: 1 250 + maxItems: 7 251 + items: 252 + minItems: 11 253 + maxItems: 11 254 + 255 + paths-ru-bf: 256 + $ref: /schemas/types.yaml#/definitions/uint8-matrix 257 + description: 258 + Sets of half-dBm backoff (beamforming) values for 802.11ax 259 + rates for 1T1ss (aka 1 transmitting antenna with 1 spacial 260 + stream), 2T1ss, 3T1ss, 4T1ss, 2T2ss, 3T2ss, 4T2ss, 3T3ss, 261 + 4T3ss and 4T4ss. 262 + Each set starts with the number of channel bandwidth or 263 + resource unit settings for which the rate set applies, 264 + followed by 10 power limit values. The order of the 265 + channel resource unit settings is RU26, RU52, RU106, 266 + RU242/SU20, RU484/SU40, RU996/SU80 and RU2x996/SU160. 267 + minItems: 1 268 + maxItems: 7 269 + items: 270 + minItems: 11 271 + maxItems: 11 218 272 219 273 txs-delta: 220 274 $ref: /schemas/types.yaml#/definitions/uint32-array
+14
drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
··· 24 24 BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" 25 25 }; 26 26 27 + static const struct brcmf_dmi_data acer_a1_840_data = { 28 + BRCM_CC_43340_CHIP_ID, 2, "acer-a1-840" 29 + }; 30 + 27 31 /* The Chuwi Hi8 Pro uses the same Ampak AP6212 module as the Chuwi Vi8 Plus 28 32 * and the nvram for the Vi8 Plus is already in linux-firmware, so use that. 29 33 */ ··· 94 90 DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), 95 91 }, 96 92 .driver_data = (void *)&acepc_t8_data, 93 + }, 94 + { 95 + /* Acer Iconia One 8 A1-840 (non FHD version) */ 96 + .matches = { 97 + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), 98 + DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), 99 + /* Above strings are too generic also match BIOS date */ 100 + DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), 101 + }, 102 + .driver_data = (void *)&acer_a1_840_data, 97 103 }, 98 104 { 99 105 /* Chuwi Hi8 Pro with D2D3_Hi8Pro.233 BIOS */
+3 -3
drivers/net/wireless/intel/ipw2x00/ipw2100.c
··· 2143 2143 2144 2144 /* Make sure the RF Kill check timer is running */ 2145 2145 priv->stop_rf_kill = 0; 2146 - mod_delayed_work(system_wq, &priv->rf_kill, round_jiffies_relative(HZ)); 2146 + mod_delayed_work(system_percpu_wq, &priv->rf_kill, round_jiffies_relative(HZ)); 2147 2147 } 2148 2148 2149 2149 static void ipw2100_scan_event(struct work_struct *work) ··· 2170 2170 round_jiffies_relative(msecs_to_jiffies(4000))); 2171 2171 } else { 2172 2172 priv->user_requested_scan = 0; 2173 - mod_delayed_work(system_wq, &priv->scan_event, 0); 2173 + mod_delayed_work(system_percpu_wq, &priv->scan_event, 0); 2174 2174 } 2175 2175 } 2176 2176 ··· 4252 4252 "disabled by HW switch\n"); 4253 4253 /* Make sure the RF_KILL check timer is running */ 4254 4254 priv->stop_rf_kill = 0; 4255 - mod_delayed_work(system_wq, &priv->rf_kill, 4255 + mod_delayed_work(system_percpu_wq, &priv->rf_kill, 4256 4256 round_jiffies_relative(HZ)); 4257 4257 } else 4258 4258 schedule_reset(priv);
+1 -1
drivers/net/wireless/intel/ipw2x00/ipw2200.c
··· 4415 4415 round_jiffies_relative(msecs_to_jiffies(4000))); 4416 4416 } else { 4417 4417 priv->user_requested_scan = 0; 4418 - mod_delayed_work(system_wq, &priv->scan_event, 0); 4418 + mod_delayed_work(system_percpu_wq, &priv->scan_event, 0); 4419 4419 } 4420 4420 } 4421 4421
+5 -1
drivers/net/wireless/mediatek/mt76/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT76_CORE 3 3 tristate 4 4 select PAGE_POOL ··· 36 36 config MT792x_USB 37 37 tristate 38 38 select MT76_USB 39 + 40 + config MT76_NPU 41 + bool 42 + depends on MT76_CORE 39 43 40 44 source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig" 41 45 source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig"
+2 -1
drivers/net/wireless/mediatek/mt76/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 obj-$(CONFIG_MT76_CORE) += mt76.o 3 3 obj-$(CONFIG_MT76_USB) += mt76-usb.o 4 4 obj-$(CONFIG_MT76_SDIO) += mt76-sdio.o ··· 12 12 mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ 13 13 tx.o agg-rx.o mcu.o wed.o scan.o channel.o 14 14 15 + mt76-$(CONFIG_MT76_NPU) += npu.o 15 16 mt76-$(CONFIG_PCI) += pci.o 16 17 mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o 17 18
+1 -1
drivers/net/wireless/mediatek/mt76/agg-rx.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/channel.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2024 Felix Fietkau <nbd@nbd.name> 4 4 */
+3 -3
drivers/net/wireless/mediatek/mt76/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 93 93 { 94 94 int i; 95 95 96 - seq_printf(file, "%10s:", str); 96 + seq_printf(file, "%16s:", str); 97 97 for (i = 0; i < len; i++) 98 - seq_printf(file, " %2d", val[i]); 98 + seq_printf(file, " %4d", val[i]); 99 99 seq_puts(file, "\n"); 100 100 } 101 101 EXPORT_SYMBOL_GPL(mt76_seq_puts_array);
+37 -38
drivers/net/wireless/mediatek/mt76/dma.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 6 6 #include <linux/dma-mapping.h> 7 7 #include "mt76.h" 8 8 #include "dma.h" 9 - 10 - #if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) 11 - 12 - #define Q_READ(_q, _field) ({ \ 13 - u32 _offset = offsetof(struct mt76_queue_regs, _field); \ 14 - u32 _val; \ 15 - if ((_q)->flags & MT_QFLAG_WED) \ 16 - _val = mtk_wed_device_reg_read((_q)->wed, \ 17 - ((_q)->wed_regs + \ 18 - _offset)); \ 19 - else \ 20 - _val = readl(&(_q)->regs->_field); \ 21 - _val; \ 22 - }) 23 - 24 - #define Q_WRITE(_q, _field, _val) do { \ 25 - u32 _offset = offsetof(struct mt76_queue_regs, _field); \ 26 - if ((_q)->flags & MT_QFLAG_WED) \ 27 - mtk_wed_device_reg_write((_q)->wed, \ 28 - ((_q)->wed_regs + _offset), \ 29 - _val); \ 30 - else \ 31 - writel(_val, &(_q)->regs->_field); \ 32 - } while (0) 33 - 34 - #else 35 - 36 - #define Q_READ(_q, _field) readl(&(_q)->regs->_field) 37 - #define Q_WRITE(_q, _field, _val) writel(_val, &(_q)->regs->_field) 38 - 39 - #endif 40 9 41 10 static struct mt76_txwi_cache * 42 11 mt76_alloc_txwi(struct mt76_dev *dev) ··· 189 220 mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q) 190 221 { 191 222 Q_WRITE(q, desc_base, q->desc_dma); 192 - if (q->flags & MT_QFLAG_WED_RRO_EN) 223 + if ((q->flags & MT_QFLAG_WED_RRO_EN) && !mt76_npu_device_active(dev)) 193 224 Q_WRITE(q, ring_size, MT_DMA_RRO_EN | q->ndesc); 194 225 else 195 226 Q_WRITE(q, ring_size, q->ndesc); 227 + 228 + if (mt76_queue_is_npu_tx(q)) { 229 + writel(q->desc_dma, &q->regs->desc_base); 230 + writel(q->ndesc, &q->regs->ring_size); 231 + } 196 232 q->head = Q_READ(q, dma_idx); 197 233 q->tail = q->head; 198 234 } ··· 209 235 return; 210 236 211 237 if (!mt76_queue_is_wed_rro_ind(q) && 212 - !mt76_queue_is_wed_rro_rxdmad_c(q)) { 238 + !mt76_queue_is_wed_rro_rxdmad_c(q) && !mt76_queue_is_npu(q)) { 213 239 int i; 214 240 215 241 /* clear descriptors */ ··· 420 446 421 447 while (q->queued > 0 && q->tail != last) { 422 448 mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry); 449 + mt76_npu_txdesc_cleanup(q, q->tail); 423 450 mt76_queue_tx_complete(dev, q, &entry); 424 451 425 452 if (entry.txwi) { ··· 655 680 if (test_bit(MT76_RESET, &phy->state)) 656 681 goto free_skb; 657 682 683 + /* TODO: Take into account unlinear skbs */ 684 + if (mt76_npu_device_active(dev) && skb_linearize(skb)) 685 + goto free_skb; 686 + 658 687 t = mt76_get_txwi(dev); 659 688 if (!t) 660 689 goto free_skb; ··· 705 726 DMA_TO_DEVICE); 706 727 if (ret < 0) 707 728 goto unmap; 729 + 730 + if (mt76_npu_device_active(dev)) 731 + return mt76_npu_dma_add_buf(phy, q, skb, &tx_info.buf[1], txwi); 708 732 709 733 return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf, 710 734 tx_info.info, tx_info.skb, t); ··· 807 825 q->ndesc = n_desc; 808 826 q->buf_size = bufsize; 809 827 q->hw_idx = idx; 828 + q->dev = dev; 810 829 811 - size = mt76_queue_is_wed_rro_ind(q) ? sizeof(struct mt76_wed_rro_desc) 812 - : sizeof(struct mt76_desc); 830 + if (mt76_queue_is_wed_rro_ind(q)) 831 + size = sizeof(struct mt76_wed_rro_desc); 832 + else if (mt76_queue_is_npu_tx(q)) 833 + size = sizeof(struct airoha_npu_tx_dma_desc); 834 + else if (mt76_queue_is_npu_rx(q)) 835 + size = sizeof(struct airoha_npu_rx_dma_desc); 836 + else 837 + size = sizeof(struct mt76_desc); 838 + 813 839 q->desc = dmam_alloc_coherent(dev->dma_dev, q->ndesc * size, 814 840 &q->desc_dma, GFP_KERNEL); 815 841 if (!q->desc) ··· 833 843 if (ret) 834 844 return ret; 835 845 846 + mt76_npu_queue_setup(dev, q); 836 847 ret = mt76_wed_dma_setup(dev, q, false); 837 848 if (ret) 838 849 return ret; ··· 860 869 861 870 if (!q->ndesc) 862 871 return; 872 + 873 + if (mt76_queue_is_npu(q)) { 874 + mt76_npu_queue_cleanup(dev, q); 875 + return; 876 + } 863 877 864 878 do { 865 879 spin_lock_bh(&q->lock); ··· 896 900 return; 897 901 898 902 if (!mt76_queue_is_wed_rro_ind(q) && 899 - !mt76_queue_is_wed_rro_rxdmad_c(q)) { 903 + !mt76_queue_is_wed_rro_rxdmad_c(q) && !mt76_queue_is_npu(q)) { 900 904 int i; 901 905 902 906 for (i = 0; i < q->ndesc; i++) ··· 916 920 return; 917 921 918 922 mt76_dma_sync_idx(dev, q); 919 - mt76_dma_rx_fill_buf(dev, q, false); 923 + if (mt76_queue_is_npu(q)) 924 + mt76_npu_fill_rx_queue(dev, q); 925 + else 926 + mt76_dma_rx_fill(dev, q, false); 920 927 } 921 928 922 929 static void
+68 -1
drivers/net/wireless/mediatek/mt76/dma.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 45 45 #define MT_RX_INFO_LEN 4 46 46 #define MT_FCE_INFO_LEN 4 47 47 #define MT_RX_RXWI_LEN 32 48 + 49 + #if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) 50 + 51 + #define Q_READ(_q, _field) ({ \ 52 + u32 _offset = offsetof(struct mt76_queue_regs, _field); \ 53 + u32 _val; \ 54 + if ((_q)->flags & MT_QFLAG_WED) \ 55 + _val = mtk_wed_device_reg_read((_q)->wed, \ 56 + ((_q)->wed_regs + \ 57 + _offset)); \ 58 + else \ 59 + _val = readl(&(_q)->regs->_field); \ 60 + _val; \ 61 + }) 62 + 63 + #define Q_WRITE(_q, _field, _val) do { \ 64 + u32 _offset = offsetof(struct mt76_queue_regs, _field); \ 65 + if ((_q)->flags & MT_QFLAG_WED) \ 66 + mtk_wed_device_reg_write((_q)->wed, \ 67 + ((_q)->wed_regs + _offset), \ 68 + _val); \ 69 + else \ 70 + writel(_val, &(_q)->regs->_field); \ 71 + } while (0) 72 + 73 + #elif IS_ENABLED(CONFIG_MT76_NPU) 74 + 75 + #define Q_READ(_q, _field) ({ \ 76 + u32 _offset = offsetof(struct mt76_queue_regs, _field); \ 77 + u32 _val = 0; \ 78 + if ((_q)->flags & MT_QFLAG_NPU) { \ 79 + struct airoha_npu *npu; \ 80 + \ 81 + rcu_read_lock(); \ 82 + npu = rcu_dereference(q->dev->mmio.npu); \ 83 + if (npu) \ 84 + regmap_read(npu->regmap, \ 85 + ((_q)->wed_regs + _offset), &_val); \ 86 + rcu_read_unlock(); \ 87 + } else { \ 88 + _val = readl(&(_q)->regs->_field); \ 89 + } \ 90 + _val; \ 91 + }) 92 + 93 + #define Q_WRITE(_q, _field, _val) do { \ 94 + u32 _offset = offsetof(struct mt76_queue_regs, _field); \ 95 + if ((_q)->flags & MT_QFLAG_NPU) { \ 96 + struct airoha_npu *npu; \ 97 + \ 98 + rcu_read_lock(); \ 99 + npu = rcu_dereference(q->dev->mmio.npu); \ 100 + if (npu) \ 101 + regmap_write(npu->regmap, \ 102 + ((_q)->wed_regs + _offset), _val); \ 103 + rcu_read_unlock(); \ 104 + } else { \ 105 + writel(_val, &(_q)->regs->_field); \ 106 + } \ 107 + } while (0) 108 + 109 + #else 110 + 111 + #define Q_READ(_q, _field) readl(&(_q)->regs->_field) 112 + #define Q_WRITE(_q, _field, _val) writel(_val, &(_q)->regs->_field) 113 + 114 + #endif 48 115 49 116 struct mt76_desc { 50 117 __le32 buf0;
+58 -19
drivers/net/wireless/mediatek/mt76/eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 253 253 return prop->value; 254 254 } 255 255 256 + static const s8 * 257 + mt76_get_of_array_s8(struct device_node *np, char *name, size_t *len, int min) 258 + { 259 + struct property *prop = of_find_property(np, name, NULL); 260 + 261 + if (!prop || !prop->value || prop->length < min) 262 + return NULL; 263 + 264 + *len = prop->length; 265 + 266 + return prop->value; 267 + } 268 + 256 269 struct device_node * 257 270 mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan) 258 271 { ··· 307 294 } 308 295 309 296 static void 310 - mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data, 297 + mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data, 311 298 s8 target_power, s8 nss_delta, s8 *max_power) 312 299 { 313 300 int i; ··· 316 303 return; 317 304 318 305 for (i = 0; i < pwr_len; i++) { 319 - pwr[i] = min_t(s8, target_power, 320 - be32_to_cpu(data[i]) + nss_delta); 306 + pwr[i] = min_t(s8, target_power, data[i] + nss_delta); 321 307 *max_power = max(*max_power, pwr[i]); 322 308 } 323 309 } 324 310 325 311 static void 326 312 mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num, 327 - const __be32 *data, size_t len, s8 target_power, 328 - s8 nss_delta, s8 *max_power) 313 + const s8 *data, size_t len, s8 target_power, 314 + s8 nss_delta) 329 315 { 330 316 int i, cur; 317 + s8 max_power = -128; 331 318 332 319 if (!data) 333 320 return; 334 321 335 - len /= 4; 336 - cur = be32_to_cpu(data[0]); 322 + cur = data[0]; 337 323 for (i = 0; i < pwr_num; i++) { 338 324 if (len < pwr_len + 1) 339 325 break; 340 326 341 327 mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1, 342 - target_power, nss_delta, max_power); 328 + target_power, nss_delta, &max_power); 343 329 if (--cur > 0) 344 330 continue; 345 331 ··· 347 335 if (!len) 348 336 break; 349 337 350 - cur = be32_to_cpu(data[0]); 338 + cur = data[0]; 351 339 } 352 340 } 353 341 ··· 358 346 { 359 347 struct mt76_dev *dev = phy->dev; 360 348 struct device_node *np; 361 - const __be32 *val; 349 + const s8 *val; 362 350 char name[16]; 363 351 u32 mcs_rates = dev->drv->mcs_rates; 364 352 u32 ru_rates = ARRAY_SIZE(dest->ru[0]); 365 353 char band; 366 354 size_t len; 367 355 s8 max_power = 0; 356 + s8 max_power_backoff = -127; 368 357 s8 txs_delta; 358 + int n_chains = hweight16(phy->chainmask); 359 + s8 target_power_combine = target_power + mt76_tx_power_path_delta(n_chains); 369 360 370 361 if (!mcs_rates) 371 362 mcs_rates = 10; 372 363 373 - memset(dest, target_power, sizeof(*dest)); 364 + memset(dest, target_power, sizeof(*dest) - sizeof(dest->path)); 365 + memset(&dest->path, 0, sizeof(dest->path)); 374 366 375 367 if (!IS_ENABLED(CONFIG_OF)) 376 368 return target_power; ··· 408 392 409 393 txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask)); 410 394 411 - val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck)); 395 + val = mt76_get_of_array_s8(np, "rates-cck", &len, ARRAY_SIZE(dest->cck)); 412 396 mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val, 413 397 target_power, txs_delta, &max_power); 414 398 415 - val = mt76_get_of_array(np, "rates-ofdm", 416 - &len, ARRAY_SIZE(dest->ofdm)); 399 + val = mt76_get_of_array_s8(np, "rates-ofdm", 400 + &len, ARRAY_SIZE(dest->ofdm)); 417 401 mt76_apply_array_limit(dest->ofdm, ARRAY_SIZE(dest->ofdm), val, 418 402 target_power, txs_delta, &max_power); 419 403 420 - val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1); 404 + val = mt76_get_of_array_s8(np, "rates-mcs", &len, mcs_rates + 1); 421 405 mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]), 422 406 ARRAY_SIZE(dest->mcs), val, len, 423 - target_power, txs_delta, &max_power); 407 + target_power, txs_delta); 424 408 425 - val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1); 409 + val = mt76_get_of_array_s8(np, "rates-ru", &len, ru_rates + 1); 426 410 mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]), 427 411 ARRAY_SIZE(dest->ru), val, len, 428 - target_power, txs_delta, &max_power); 412 + target_power, txs_delta); 413 + 414 + max_power_backoff = max_power; 415 + val = mt76_get_of_array_s8(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck)); 416 + mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val, 417 + target_power_combine, txs_delta, &max_power_backoff); 418 + 419 + val = mt76_get_of_array_s8(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm)); 420 + mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val, 421 + target_power_combine, txs_delta, &max_power_backoff); 422 + 423 + val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf)); 424 + mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val, 425 + target_power_combine, txs_delta, &max_power_backoff); 426 + 427 + val = mt76_get_of_array_s8(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1); 428 + mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]), 429 + ARRAY_SIZE(dest->path.ru), val, len, 430 + target_power_combine, txs_delta); 431 + 432 + val = mt76_get_of_array_s8(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1); 433 + mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]), 434 + ARRAY_SIZE(dest->path.ru_bf), val, len, 435 + target_power_combine, txs_delta); 429 436 430 437 return max_power; 431 438 }
+6 -4
drivers/net/wireless/mediatek/mt76/mac80211.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 630 630 case MT_RXQ_MAIN: 631 631 case MT_RXQ_BAND1: 632 632 case MT_RXQ_BAND2: 633 + case MT_RXQ_NPU0: 634 + case MT_RXQ_NPU1: 633 635 pp_params.pool_size = 256; 634 636 break; 635 637 default: ··· 816 814 destroy_workqueue(dev->wq); 817 815 dev->wq = NULL; 818 816 } 817 + mt76_npu_deinit(dev); 819 818 ieee80211_free_hw(dev->hw); 820 819 } 821 820 EXPORT_SYMBOL_GPL(mt76_free_device); ··· 849 846 rcu_assign_pointer(dev->wcid[i], NULL); 850 847 } 851 848 rcu_read_unlock(); 852 - 853 - mt76_abort_scan(dev); 854 849 855 850 INIT_LIST_HEAD(&dev->wcid_list); 856 851 INIT_LIST_HEAD(&dev->sta_poll_list); ··· 1554 1553 1555 1554 while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) { 1556 1555 mt76_check_sta(dev, skb); 1557 - if (mtk_wed_device_active(&dev->mmio.wed)) 1556 + if (mtk_wed_device_active(&dev->mmio.wed) || 1557 + mt76_npu_device_active(dev)) 1558 1558 __skb_queue_tail(&frames, skb); 1559 1559 else 1560 1560 mt76_rx_aggr_reorder(skb, &frames);
+1 -1
drivers/net/wireless/mediatek/mt76/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+11 -3
drivers/net/wireless/mediatek/mt76/mmio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 33 33 static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset, 34 34 const void *data, int len) 35 35 { 36 - __iowrite32_copy(dev->mmio.regs + offset, data, DIV_ROUND_UP(len, 4)); 36 + int i; 37 + 38 + for (i = 0; i < ALIGN(len, 4); i += 4) 39 + writel(get_unaligned_le32(data + i), 40 + dev->mmio.regs + offset + i); 37 41 } 38 42 39 43 static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset, 40 44 void *data, int len) 41 45 { 42 - __ioread32_copy(data, dev->mmio.regs + offset, DIV_ROUND_UP(len, 4)); 46 + int i; 47 + 48 + for (i = 0; i < ALIGN(len, 4); i += 4) 49 + put_unaligned_le32(readl(dev->mmio.regs + offset + i), 50 + data + i); 43 51 } 44 52 45 53 static int mt76_mmio_wr_rp(struct mt76_dev *dev, u32 base,
+157 -2
drivers/net/wireless/mediatek/mt76/mt76.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 13 13 #include <linux/leds.h> 14 14 #include <linux/usb.h> 15 15 #include <linux/average.h> 16 + #include <linux/soc/airoha/airoha_offload.h> 16 17 #include <linux/soc/mediatek/mtk_wed.h> 17 18 #include <net/mac80211.h> 18 19 #include <net/page_pool/helpers.h> ··· 35 34 #define MT_QFLAG_WED_RRO BIT(6) 36 35 #define MT_QFLAG_WED_RRO_EN BIT(7) 37 36 #define MT_QFLAG_EMI_EN BIT(8) 37 + #define MT_QFLAG_NPU BIT(9) 38 38 39 39 #define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \ 40 40 FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ ··· 49 47 #define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n) 50 48 #define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0) 51 49 #define MT_WED_RRO_Q_RXDMAD_C __MT_WED_RRO_Q(MT76_WED_RRO_Q_RXDMAD_C, 0) 50 + 51 + #define __MT_NPU_Q(_type, _n) (MT_QFLAG_NPU | \ 52 + FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ 53 + FIELD_PREP(MT_QFLAG_WED_RING, _n)) 54 + #define MT_NPU_Q_TX(_n) __MT_NPU_Q(MT76_WED_Q_TX, _n) 55 + #define MT_NPU_Q_RX(_n) __MT_NPU_Q(MT76_WED_Q_RX, _n) 52 56 53 57 struct mt76_dev; 54 58 struct mt76_phy; ··· 147 139 MT_RXQ_TXFREE_BAND2, 148 140 MT_RXQ_RRO_IND, 149 141 MT_RXQ_RRO_RXDMAD_C, 142 + MT_RXQ_NPU0, 143 + MT_RXQ_NPU1, 150 144 __MT_RXQ_MAX 151 145 }; 152 146 ··· 257 247 __le16 *emi_cpu_idx; 258 248 259 249 struct mtk_wed_device *wed; 250 + struct mt76_dev *dev; 260 251 u32 wed_regs; 261 252 262 253 dma_addr_t desc_dma; ··· 717 706 struct mtk_wed_device wed_hif2; 718 707 struct completion wed_reset; 719 708 struct completion wed_reset_complete; 709 + 710 + struct airoha_ppe_dev __rcu *ppe_dev; 711 + struct airoha_npu __rcu *npu; 712 + phys_addr_t phy_addr; 713 + int npu_type; 720 714 }; 721 715 722 716 struct mt76_rx_status { ··· 959 943 struct idr token; 960 944 u16 wed_token_count; 961 945 u16 token_count; 946 + u16 token_start; 962 947 u16 token_size; 963 948 964 949 spinlock_t rx_token_lock; ··· 1130 1113 s8 mcs[4][10]; 1131 1114 s8 ru[7][12]; 1132 1115 s8 eht[16][16]; 1116 + 1117 + struct { 1118 + s8 cck[4]; 1119 + s8 ofdm[4]; 1120 + s8 ofdm_bf[4]; 1121 + s8 ru[7][10]; 1122 + s8 ru_bf[7][10]; 1123 + } path; 1133 1124 }; 1134 1125 1135 1126 struct mt76_ethtool_worker_info { ··· 1276 1251 1277 1252 #define mt76_dereference(p, dev) \ 1278 1253 rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex)) 1254 + 1255 + static inline struct mt76_dev *mt76_wed_to_dev(struct mtk_wed_device *wed) 1256 + { 1257 + #ifdef CONFIG_NET_MEDIATEK_SOC_WED 1258 + if (wed->wlan.hif2) 1259 + return container_of(wed, struct mt76_dev, mmio.wed_hif2); 1260 + #endif /* CONFIG_NET_MEDIATEK_SOC_WED */ 1261 + return container_of(wed, struct mt76_dev, mmio.wed); 1262 + } 1279 1263 1280 1264 static inline struct mt76_wcid * 1281 1265 __mt76_wcid_ptr(struct mt76_dev *dev, u16 idx) ··· 1632 1598 int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); 1633 1599 int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); 1634 1600 1601 + #ifdef CONFIG_MT76_NPU 1602 + void mt76_npu_check_ppe(struct mt76_dev *dev, struct sk_buff *skb, 1603 + u32 info); 1604 + int mt76_npu_dma_add_buf(struct mt76_phy *phy, struct mt76_queue *q, 1605 + struct sk_buff *skb, struct mt76_queue_buf *buf, 1606 + void *txwi_ptr); 1607 + int mt76_npu_rx_queue_init(struct mt76_dev *dev, struct mt76_queue *q); 1608 + int mt76_npu_fill_rx_queue(struct mt76_dev *dev, struct mt76_queue *q); 1609 + void mt76_npu_queue_cleanup(struct mt76_dev *dev, struct mt76_queue *q); 1610 + void mt76_npu_disable_irqs(struct mt76_dev *dev); 1611 + int mt76_npu_init(struct mt76_dev *dev, phys_addr_t phy_addr, int type); 1612 + void mt76_npu_deinit(struct mt76_dev *dev); 1613 + void mt76_npu_queue_setup(struct mt76_dev *dev, struct mt76_queue *q); 1614 + void mt76_npu_txdesc_cleanup(struct mt76_queue *q, int index); 1615 + int mt76_npu_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1616 + struct net_device *dev, enum tc_setup_type type, 1617 + void *type_data); 1618 + #else 1619 + static inline void mt76_npu_check_ppe(struct mt76_dev *dev, 1620 + struct sk_buff *skb, u32 info) 1621 + { 1622 + } 1623 + 1624 + static inline int mt76_npu_dma_add_buf(struct mt76_phy *phy, 1625 + struct mt76_queue *q, 1626 + struct sk_buff *skb, 1627 + struct mt76_queue_buf *buf, 1628 + void *txwi_ptr) 1629 + { 1630 + return -EOPNOTSUPP; 1631 + } 1632 + 1633 + static inline int mt76_npu_fill_rx_queue(struct mt76_dev *dev, 1634 + struct mt76_queue *q) 1635 + { 1636 + return 0; 1637 + } 1638 + 1639 + static inline void mt76_npu_queue_cleanup(struct mt76_dev *dev, 1640 + struct mt76_queue *q) 1641 + { 1642 + } 1643 + 1644 + static inline void mt76_npu_disable_irqs(struct mt76_dev *dev) 1645 + { 1646 + } 1647 + 1648 + static inline int mt76_npu_init(struct mt76_dev *dev, phys_addr_t phy_addr, 1649 + int type) 1650 + { 1651 + return 0; 1652 + } 1653 + 1654 + static inline void mt76_npu_deinit(struct mt76_dev *dev) 1655 + { 1656 + } 1657 + 1658 + static inline void mt76_npu_queue_setup(struct mt76_dev *dev, 1659 + struct mt76_queue *q) 1660 + { 1661 + } 1662 + 1663 + static inline void mt76_npu_txdesc_cleanup(struct mt76_queue *q, 1664 + int index) 1665 + { 1666 + } 1667 + 1668 + static inline int mt76_npu_net_setup_tc(struct ieee80211_hw *hw, 1669 + struct ieee80211_vif *vif, 1670 + struct net_device *dev, 1671 + enum tc_setup_type type, 1672 + void *type_data) 1673 + { 1674 + return -EOPNOTSUPP; 1675 + } 1676 + #endif /* CONFIG_MT76_NPU */ 1677 + 1678 + static inline bool mt76_npu_device_active(struct mt76_dev *dev) 1679 + { 1680 + return !!rcu_access_pointer(dev->mmio.npu); 1681 + } 1682 + 1683 + static inline bool mt76_ppe_device_active(struct mt76_dev *dev) 1684 + { 1685 + return !!rcu_access_pointer(dev->mmio.ppe_dev); 1686 + } 1687 + 1688 + static inline int mt76_npu_send_msg(struct airoha_npu *npu, int ifindex, 1689 + enum airoha_npu_wlan_set_cmd cmd, 1690 + u32 val, gfp_t gfp) 1691 + { 1692 + return airoha_npu_wlan_send_msg(npu, ifindex, cmd, &val, sizeof(val), 1693 + gfp); 1694 + } 1695 + 1696 + static inline int mt76_npu_get_msg(struct airoha_npu *npu, int ifindex, 1697 + enum airoha_npu_wlan_get_cmd cmd, 1698 + u32 *val, gfp_t gfp) 1699 + { 1700 + return airoha_npu_wlan_get_msg(npu, ifindex, cmd, val, sizeof(*val), 1701 + gfp); 1702 + } 1703 + 1635 1704 static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) 1636 1705 { 1637 1706 #ifdef CONFIG_NL80211_TESTMODE ··· 1976 1839 return q->flags & MT_QFLAG_EMI_EN; 1977 1840 } 1978 1841 1842 + static inline bool mt76_queue_is_npu(struct mt76_queue *q) 1843 + { 1844 + return q->flags & MT_QFLAG_NPU; 1845 + } 1846 + 1847 + static inline bool mt76_queue_is_npu_tx(struct mt76_queue *q) 1848 + { 1849 + return mt76_queue_is_npu(q) && 1850 + FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TX; 1851 + } 1852 + 1853 + static inline bool mt76_queue_is_npu_rx(struct mt76_queue *q) 1854 + { 1855 + return mt76_queue_is_npu(q) && 1856 + FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX; 1857 + } 1858 + 1979 1859 struct mt76_txwi_cache * 1980 1860 mt76_token_release(struct mt76_dev *dev, int token, bool *wake); 1981 1861 int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); ··· 2014 1860 { 2015 1861 struct page *page; 2016 1862 2017 - page = page_pool_dev_alloc_frag(q->page_pool, offset, size); 1863 + page = page_pool_alloc_frag(q->page_pool, offset, size, 1864 + GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32); 2018 1865 if (!page) 2019 1866 return NULL; 2020 1867
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT7603E 3 3 tristate "MediaTek MT7603E (PCIe) and MT76x8 WLAN support" 4 4 select MT76_CORE
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 obj-$(CONFIG_MT7603E) += mt7603e.o 3 3 4 4 mt7603e-y := \
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7603.h" 4 4
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/core.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7603.h" 4 4 #include "../trace.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7603.h" 4 4
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/dma.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7603.h" 4 4 #include "mac.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/of.h> 4 4 #include "mt7603.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/eeprom.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 3 3 #ifndef __MT7603_EEPROM_H 4 4 #define __MT7603_EEPROM_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/etherdevice.h> 4 4 #include "mt7603.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/etherdevice.h> 4 4 #include <linux/timekeeping.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 3 3 #ifndef __MT7603_MAC_H 4 4 #define __MT7603_MAC_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/etherdevice.h> 4 4 #include <linux/platform_device.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/firmware.h> 4 4 #include "mt7603.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 3 3 #ifndef __MT7603_MCU_H 4 4 #define __MT7603_MCU_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 3 3 #ifndef __MT7603_H 4 4 #define __MT7603_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/kernel.h> 4 4 #include <linux/module.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 3 3 #ifndef __MT7603_REGS_H 4 4 #define __MT7603_REGS_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7603/soc.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include <linux/kernel.h> 4 4 #include <linux/module.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 config MT7615_COMMON 4 4 tristate
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/Makefile
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o 4 4 obj-$(CONFIG_MT7615E) += mt7615e.o
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7615.h" 4 4
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/dma.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2019 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7615_EEPROM_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Roy Luo <royluo@google.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2019 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7615_MAC_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Roy Luo <royluo@google.com>
+4 -2
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Roy Luo <royluo@google.com> ··· 874 874 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, 875 875 WTBL_RESET_AND_SET, NULL, 876 876 &wskb); 877 - if (IS_ERR(wtbl_hdr)) 877 + if (IS_ERR(wtbl_hdr)) { 878 + dev_kfree_skb(sskb); 878 879 return PTR_ERR(wtbl_hdr); 880 + } 879 881 880 882 if (enable) { 881 883 mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta,
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2019 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7615_MCU_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/mmio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/kernel.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2019 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7615_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/mt7615_trace.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Roy Luo <royluo@google.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2019 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7615_REGS_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/sdio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * Author: Felix Fietkau <nbd@nbd.name>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/soc.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/testmode.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */ 3 3 4 4 #include "mt7615.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/trace.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/usb.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2019 MediaTek Inc. 3 3 * 4 4 * Author: Felix Fietkau <nbd@nbd.name>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76_connac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT76_CONNAC_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt76_connac2_mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2022 MediaTek Inc. */ 3 3 4 4 #ifndef __MT76_CONNAC2_MAC_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include "mt76_connac.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT76_CONNAC3_MAC_H
+12 -9
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include "mt76_connac.h" ··· 297 297 struct ieee80211_bss_conf *conf, 298 298 bool beacon, bool mcast) 299 299 { 300 - struct mt76_vif_link *mvif = mt76_vif_conf_link(mphy->dev, conf->vif, conf); 301 - struct cfg80211_chan_def *chandef = mvif->ctx ? 302 - &mvif->ctx->def : &mphy->chandef; 303 - u8 nss = 0, mode = 0, band = chandef->chan->band; 304 - int rateidx = 0, mcast_rate; 305 - int offset = 0; 300 + u8 nss = 0, mode = 0, band = NL80211_BAND_2GHZ; 301 + int rateidx = 0, offset = 0, mcast_rate; 302 + struct cfg80211_chan_def *chandef; 303 + struct mt76_vif_link *mvif; 306 304 307 305 if (!conf) 308 306 goto legacy; 307 + 308 + mvif = mt76_vif_conf_link(mphy->dev, conf->vif, conf); 309 + chandef = mvif->ctx ? &mvif->ctx->def : &mphy->chandef; 310 + band = chandef->chan->band; 309 311 310 312 if (is_mt7921(mphy->dev)) { 311 313 rateidx = ffs(conf->basic_rates) - 1; ··· 586 584 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 587 585 bool multicast = ieee80211_is_data(hdr->frame_control) && 588 586 is_multicast_ether_addr(hdr->addr1); 589 - u16 rate = mt76_connac2_mac_tx_rate_val(mphy, &vif->bss_conf, beacon, 590 - multicast); 587 + u16 rate = mt76_connac2_mac_tx_rate_val(mphy, 588 + vif ? &vif->bss_conf : NULL, 589 + beacon, multicast); 591 590 u32 val = MT_TXD6_FIXED_BW; 592 591 593 592 /* hardware won't add HTC for mgmt/ctrl frame */
+7 -3
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/firmware.h> ··· 1974 1974 .resp_type = 0, 1975 1975 }; 1976 1976 1977 - memcpy(req.data, "assert", 7); 1977 + strscpy(req.data, "assert"); 1978 1978 1979 1979 return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG), 1980 1980 &req, sizeof(req), false); ··· 3101 3101 int i, ret, sem, max_len = mt76_is_sdio(dev) ? 2048 : 4096; 3102 3102 const struct mt76_connac2_patch_hdr *hdr; 3103 3103 const struct firmware *fw = NULL; 3104 + char build_date[17]; 3104 3105 3105 3106 sem = mt76_connac_mcu_patch_sem_ctrl(dev, true); 3106 3107 switch (sem) { ··· 3125 3124 } 3126 3125 3127 3126 hdr = (const void *)fw->data; 3127 + strscpy(build_date, hdr->build_date, sizeof(build_date)); 3128 + build_date[16] = '\0'; 3129 + strim(build_date); 3128 3130 dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n", 3129 - be32_to_cpu(hdr->hw_sw_ver), hdr->build_date); 3131 + be32_to_cpu(hdr->hw_sw_ver), build_date); 3130 3132 3131 3133 for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) { 3132 3134 struct mt76_connac2_patch_sec *sec;
+3 -1
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT76_CONNAC_MCU_H ··· 1062 1062 MCU_UNI_EVENT_ROC = 0x27, 1063 1063 MCU_UNI_EVENT_TX_DONE = 0x2d, 1064 1064 MCU_UNI_EVENT_THERMAL = 0x35, 1065 + MCU_UNI_EVENT_RSSI_MONITOR = 0x41, 1065 1066 MCU_UNI_EVENT_NIC_CAPAB = 0x43, 1066 1067 MCU_UNI_EVENT_WED_RRO = 0x57, 1067 1068 MCU_UNI_EVENT_PER_STA_INFO = 0x6d, ··· 1301 1300 MCU_UNI_CMD_THERMAL = 0x35, 1302 1301 MCU_UNI_CMD_VOW = 0x37, 1303 1302 MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40, 1303 + MCU_UNI_CMD_RSSI_MONITOR = 0x41, 1304 1304 MCU_UNI_CMD_TESTMODE_CTRL = 0x46, 1305 1305 MCU_UNI_CMD_RRO = 0x57, 1306 1306 MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x0/pci_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x0/usb_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_dfs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_dma.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_phy.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_phy.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_trace.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_trace.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_usb_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x02_util.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl> 4 4 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT76x2_COMMON 3 3 tristate 4 4 select MT76x02_LIB
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o 3 3 obj-$(CONFIG_MT76x2E) += mt76x2e.o 4 4 obj-$(CONFIG_MT76x2U) += mt76x2u.o
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/phy.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/Kconfig
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT7915E 3 3 tristate "MediaTek MT7915E (PCIe) support" 4 4 select MT76_CONNAC_LIB
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/Makefile
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 obj-$(CONFIG_MT7915E) += mt7915e.o 4 4
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/coredump.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2022 MediaTek Inc. */ 3 3 4 4 #include <linux/devcoredump.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/coredump.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2022 MediaTek Inc. */ 3 3 4 4 #ifndef _COREDUMP_H_
+71 -5
drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/relay.h> ··· 1008 1008 if (!buf) 1009 1009 return -ENOMEM; 1010 1010 1011 - ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr)); 1011 + ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr), TX_POWER_INFO_RATE); 1012 1012 if (ret) 1013 1013 goto out; 1014 1014 ··· 1118 1118 1119 1119 mutex_lock(&dev->mt76.mutex); 1120 1120 ret = mt7915_mcu_get_txpower_sku(phy, req.txpower_sku, 1121 - sizeof(req.txpower_sku)); 1121 + sizeof(req.txpower_sku), TX_POWER_INFO_RATE); 1122 1122 if (ret) 1123 1123 goto out; 1124 1124 ··· 1160 1160 return ret ? ret : count; 1161 1161 } 1162 1162 1163 - static const struct file_operations mt7915_rate_txpower_fops = { 1163 + static const struct file_operations mt7915_txpower_fops = { 1164 1164 .write = mt7915_rate_txpower_set, 1165 1165 .read = mt7915_rate_txpower_get, 1166 1166 .open = simple_open, 1167 1167 .owner = THIS_MODULE, 1168 1168 .llseek = default_llseek, 1169 1169 }; 1170 + 1171 + static int 1172 + mt7915_path_txpower_show(struct seq_file *file) 1173 + { 1174 + struct mt7915_phy *phy = file->private; 1175 + s8 txpower[MT7915_SKU_PATH_NUM], *buf = txpower; 1176 + int ret; 1177 + 1178 + #define PATH_POWER_SHOW(_name, _len, _skip) do { \ 1179 + size_t __len = (_len); \ 1180 + if (_skip) { \ 1181 + buf -= 1; \ 1182 + *buf = 0; \ 1183 + } \ 1184 + mt76_seq_puts_array(file, _name, buf, __len); \ 1185 + buf += __len; \ 1186 + } while (0) 1187 + 1188 + seq_printf(file, "\n%*c", 18, ' '); 1189 + seq_puts(file, "1T1S/2T1S/3T1S/4T1S/2T2S/3T2S/4T2S/3T3S/4T3S/4T4S\n"); 1190 + ret = mt7915_mcu_get_txpower_sku(phy, txpower, sizeof(txpower), 1191 + TX_POWER_INFO_PATH); 1192 + if (ret) 1193 + return ret; 1194 + 1195 + PATH_POWER_SHOW("CCK", 4, 0); 1196 + PATH_POWER_SHOW("OFDM", 4, 0); 1197 + PATH_POWER_SHOW("BF-OFDM", 4, 1); 1198 + 1199 + PATH_POWER_SHOW("HT/VHT20", 10, 0); 1200 + PATH_POWER_SHOW("BF-HT/VHT20", 10, 1); 1201 + PATH_POWER_SHOW("HT/VHT40", 10, 0); 1202 + PATH_POWER_SHOW("BF-HT/VHT40", 10, 1); 1203 + 1204 + PATH_POWER_SHOW("BW20/RU242", 10, 0); 1205 + PATH_POWER_SHOW("BF-BW20/RU242", 10, 1); 1206 + PATH_POWER_SHOW("BW40/RU484", 10, 0); 1207 + PATH_POWER_SHOW("BF-BW40/RU484", 10, 1); 1208 + PATH_POWER_SHOW("BW80/RU996", 10, 0); 1209 + PATH_POWER_SHOW("BF-BW80/RU996", 10, 1); 1210 + PATH_POWER_SHOW("BW160/RU2x996", 10, 0); 1211 + PATH_POWER_SHOW("BF-BW160/RU2x996", 10, 1); 1212 + PATH_POWER_SHOW("RU26", 10, 0); 1213 + PATH_POWER_SHOW("BF-RU26", 10, 0); 1214 + PATH_POWER_SHOW("RU52", 10, 0); 1215 + PATH_POWER_SHOW("BF-RU52", 10, 0); 1216 + PATH_POWER_SHOW("RU106", 10, 0); 1217 + PATH_POWER_SHOW("BF-RU106", 10, 0); 1218 + #undef PATH_POWER_SHOW 1219 + 1220 + return 0; 1221 + } 1222 + 1223 + static int 1224 + mt7915_txpower_path_show(struct seq_file *file, void *data) 1225 + { 1226 + struct mt7915_phy *phy = file->private; 1227 + 1228 + seq_printf(file, "\nBand %d\n", phy != &phy->dev->phy); 1229 + 1230 + return mt7915_path_txpower_show(file); 1231 + } 1232 + 1233 + DEFINE_SHOW_ATTRIBUTE(mt7915_txpower_path); 1170 1234 1171 1235 static int 1172 1236 mt7915_twt_stats(struct seq_file *s, void *data) ··· 1318 1254 debugfs_create_file("implicit_txbf", 0600, dir, dev, 1319 1255 &fops_implicit_txbf); 1320 1256 debugfs_create_file("txpower_sku", 0400, dir, phy, 1321 - &mt7915_rate_txpower_fops); 1257 + &mt7915_txpower_fops); 1258 + debugfs_create_file("txpower_path", 0400, dir, phy, 1259 + &mt7915_txpower_path_fops); 1322 1260 debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir, 1323 1261 mt7915_twt_stats); 1324 1262 debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval);
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/dma.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include "mt7915.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/firmware.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7915_EEPROM_H
+8 -1
drivers/net/wireless/mediatek/mt76/mt7915/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h> ··· 289 289 int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band); 290 290 struct mt76_power_limits limits; 291 291 292 + phy->sku_limit_en = true; 293 + phy->sku_path_en = true; 292 294 for (i = 0; i < sband->n_channels; i++) { 293 295 struct ieee80211_channel *chan = &sband->channels[i]; 294 296 u32 target_power = 0; ··· 307 305 target_power = mt76_get_rate_power_limits(phy->mt76, chan, 308 306 &limits, 309 307 target_power); 308 + 309 + /* MT7915N can not enable Backoff table without setting value in dts */ 310 + if (!limits.path.ofdm[0]) 311 + phy->sku_path_en = false; 312 + 310 313 target_power += path_delta; 311 314 target_power = DIV_ROUND_UP(target_power, 2); 312 315 chan->max_power = min_t(int, chan->max_reg_power,
+3 -1
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h> ··· 1450 1450 cancel_delayed_work_sync(&dev->mphy.mac_work); 1451 1451 if (ext_phy) 1452 1452 cancel_delayed_work_sync(&ext_phy->mac_work); 1453 + 1454 + mt76_abort_scan(&dev->mt76); 1453 1455 1454 1456 mutex_lock(&dev->mt76.mutex); 1455 1457 for (i = 0; i < 10; i++) {
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7915_MAC_H
+2 -2
drivers/net/wireless/mediatek/mt76/mt7915/main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h> ··· 73 73 if (ret) 74 74 goto out; 75 75 76 - ret = mt7915_mcu_set_sku_en(phy, true); 76 + ret = mt7915_mcu_set_sku_en(phy); 77 77 if (ret) 78 78 goto out; 79 79
+143 -41
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/fs.h> ··· 3336 3336 int ret; 3337 3337 s8 txpower_sku[MT7915_SKU_RATE_NUM]; 3338 3338 3339 - ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku)); 3339 + ret = mt7915_mcu_get_txpower_sku(phy, txpower_sku, sizeof(txpower_sku), 3340 + TX_POWER_INFO_RATE); 3340 3341 if (ret) 3341 3342 return ret; 3342 3343 ··· 3377 3376 sizeof(req), true); 3378 3377 } 3379 3378 3379 + static void 3380 + mt7915_update_txpower(struct mt7915_phy *phy, int tx_power) 3381 + { 3382 + struct mt76_phy *mphy = phy->mt76; 3383 + struct ieee80211_channel *chan = mphy->main_chandef.chan; 3384 + int chain_idx, val, e2p_power_limit = 0; 3385 + 3386 + if (!chan) { 3387 + mphy->txpower_cur = tx_power; 3388 + return; 3389 + } 3390 + 3391 + for (chain_idx = 0; chain_idx < hweight16(mphy->chainmask); chain_idx++) { 3392 + val = mt7915_eeprom_get_target_power(phy->dev, chan, chain_idx); 3393 + val += mt7915_eeprom_get_power_delta(phy->dev, chan->band); 3394 + 3395 + e2p_power_limit = max_t(int, e2p_power_limit, val); 3396 + } 3397 + 3398 + if (phy->sku_limit_en) 3399 + mphy->txpower_cur = min_t(int, e2p_power_limit, tx_power); 3400 + else 3401 + mphy->txpower_cur = e2p_power_limit; 3402 + } 3403 + 3380 3404 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy) 3381 3405 { 3406 + #define TX_POWER_LIMIT_TABLE_RATE 0 3407 + #define TX_POWER_LIMIT_TABLE_PATH 1 3382 3408 struct mt7915_dev *dev = phy->dev; 3383 3409 struct mt76_phy *mphy = phy->mt76; 3384 3410 struct ieee80211_hw *hw = mphy->hw; 3385 - struct mt7915_mcu_txpower_sku req = { 3411 + struct mt7915_sku_val { 3412 + u8 format_id; 3413 + u8 limit_type; 3414 + u8 band_idx; 3415 + } __packed hdr = { 3386 3416 .format_id = TX_POWER_LIMIT_TABLE, 3417 + .limit_type = TX_POWER_LIMIT_TABLE_RATE, 3387 3418 .band_idx = phy->mt76->band_idx, 3388 3419 }; 3389 - struct mt76_power_limits limits_array; 3390 - s8 *la = (s8 *)&limits_array; 3391 - int i, idx; 3392 - int tx_power; 3420 + int i, ret, tx_power; 3421 + const u8 *len = mt7915_sku_group_len; 3422 + struct mt76_power_limits la = {}; 3423 + struct sk_buff *skb; 3393 3424 3394 3425 tx_power = mt76_get_power_bound(mphy, hw->conf.power_level); 3395 - tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan, 3396 - &limits_array, tx_power); 3397 - mphy->txpower_cur = tx_power; 3398 - 3399 - for (i = 0, idx = 0; i < ARRAY_SIZE(mt7915_sku_group_len); i++) { 3400 - u8 mcs_num, len = mt7915_sku_group_len[i]; 3401 - int j; 3402 - 3403 - if (i >= SKU_HT_BW20 && i <= SKU_VHT_BW160) { 3404 - mcs_num = 10; 3405 - 3406 - if (i == SKU_HT_BW20 || i == SKU_VHT_BW20) 3407 - la = (s8 *)&limits_array + 12; 3408 - } else { 3409 - mcs_num = len; 3410 - } 3411 - 3412 - for (j = 0; j < min_t(u8, mcs_num, len); j++) 3413 - req.txpower_sku[idx + j] = la[j]; 3414 - 3415 - la += mcs_num; 3416 - idx += len; 3426 + if (phy->sku_limit_en) { 3427 + tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan, 3428 + &la, tx_power); 3429 + mt7915_update_txpower(phy, tx_power); 3430 + } else { 3431 + mt7915_update_txpower(phy, tx_power); 3432 + return 0; 3417 3433 } 3418 3434 3419 - return mt76_mcu_send_msg(&dev->mt76, 3420 - MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req, 3421 - sizeof(req), true); 3435 + skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, 3436 + sizeof(hdr) + MT7915_SKU_RATE_NUM); 3437 + if (!skb) 3438 + return -ENOMEM; 3439 + 3440 + skb_put_data(skb, &hdr, sizeof(hdr)); 3441 + skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]); 3442 + skb_put_data(skb, &la.mcs[0], len[SKU_HT_BW20]); 3443 + skb_put_data(skb, &la.mcs[1], len[SKU_HT_BW40]); 3444 + 3445 + /* vht */ 3446 + for (i = 0; i < 4; i++) { 3447 + skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i])); 3448 + skb_put_zero(skb, 2); /* padding */ 3449 + } 3450 + 3451 + /* he */ 3452 + skb_put_data(skb, &la.ru[0], sizeof(la.ru)); 3453 + ret = mt76_mcu_skb_send_msg(&dev->mt76, skb, 3454 + MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true); 3455 + if (ret) 3456 + return ret; 3457 + 3458 + /* only set per-path power table when it's configured */ 3459 + if (!phy->sku_path_en) 3460 + return 0; 3461 + 3462 + skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, 3463 + sizeof(hdr) + MT7915_SKU_PATH_NUM); 3464 + if (!skb) 3465 + return -ENOMEM; 3466 + 3467 + hdr.limit_type = TX_POWER_LIMIT_TABLE_PATH; 3468 + skb_put_data(skb, &hdr, sizeof(hdr)); 3469 + skb_put_data(skb, &la.path.cck, sizeof(la.path.cck)); 3470 + skb_put_data(skb, &la.path.ofdm, sizeof(la.path.ofdm)); 3471 + skb_put_data(skb, &la.path.ofdm_bf[1], sizeof(la.path.ofdm_bf) - 1); 3472 + 3473 + /* HT20 and HT40 */ 3474 + skb_put_data(skb, &la.path.ru[3], sizeof(la.path.ru[3])); 3475 + skb_put_data(skb, &la.path.ru_bf[3][1], sizeof(la.path.ru_bf[3]) - 1); 3476 + skb_put_data(skb, &la.path.ru[4], sizeof(la.path.ru[4])); 3477 + skb_put_data(skb, &la.path.ru_bf[4][1], sizeof(la.path.ru_bf[4]) - 1); 3478 + 3479 + /* start from non-bf and bf fields of 3480 + * BW20/RU242, BW40/RU484, BW80/RU996, BW160/RU2x996, 3481 + * RU26, RU52, and RU106 3482 + */ 3483 + 3484 + for (i = 0; i < 8; i++) { 3485 + bool bf = i % 2; 3486 + u8 idx = (i + 6) / 2; 3487 + s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx]; 3488 + /* The non-bf fields of RU26 to RU106 are special cases */ 3489 + if (bf) 3490 + skb_put_data(skb, buf + 1, 9); 3491 + else 3492 + skb_put_data(skb, buf, 10); 3493 + } 3494 + 3495 + for (i = 0; i < 6; i++) { 3496 + bool bf = i % 2; 3497 + u8 idx = i / 2; 3498 + s8 *buf = bf ? la.path.ru_bf[idx] : la.path.ru[idx]; 3499 + 3500 + skb_put_data(skb, buf, 10); 3501 + } 3502 + 3503 + return mt76_mcu_skb_send_msg(&dev->mt76, skb, 3504 + MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), true); 3422 3505 } 3423 3506 3424 - int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len) 3507 + int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len, 3508 + u8 category) 3425 3509 { 3426 3510 #define RATE_POWER_INFO 2 3427 3511 struct mt7915_dev *dev = phy->dev; ··· 3517 3431 u8 _rsv; 3518 3432 } __packed req = { 3519 3433 .format_id = TX_POWER_LIMIT_INFO, 3520 - .category = RATE_POWER_INFO, 3434 + .category = category, 3521 3435 .band_idx = phy->mt76->band_idx, 3522 3436 }; 3523 - s8 txpower_sku[MT7915_SKU_RATE_NUM][2]; 3524 3437 struct sk_buff *skb; 3525 3438 int ret, i; 3526 3439 ··· 3529 3444 if (ret) 3530 3445 return ret; 3531 3446 3532 - memcpy(txpower_sku, skb->data + 4, sizeof(txpower_sku)); 3533 - for (i = 0; i < len; i++) 3534 - txpower[i] = txpower_sku[i][req.band_idx]; 3447 + if (category == TX_POWER_INFO_RATE) { 3448 + s8 res[MT7915_SKU_RATE_NUM][2]; 3449 + 3450 + memcpy(res, skb->data + 4, sizeof(res)); 3451 + for (i = 0; i < len; i++) 3452 + txpower[i] = res[i][req.band_idx]; 3453 + } else if (category == TX_POWER_INFO_PATH) { 3454 + memcpy(txpower, skb->data + 4, len); 3455 + } 3535 3456 3536 3457 dev_kfree_skb(skb); 3537 3458 ··· 3566 3475 sizeof(req), false); 3567 3476 } 3568 3477 3569 - int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable) 3478 + int mt7915_mcu_set_sku_en(struct mt7915_phy *phy) 3570 3479 { 3571 3480 struct mt7915_dev *dev = phy->dev; 3572 3481 struct mt7915_sku { ··· 3575 3484 u8 band_idx; 3576 3485 u8 rsv; 3577 3486 } __packed req = { 3578 - .format_id = TX_POWER_LIMIT_ENABLE, 3579 3487 .band_idx = phy->mt76->band_idx, 3580 - .sku_enable = enable, 3581 3488 }; 3489 + int ret; 3490 + 3491 + req.sku_enable = phy->sku_limit_en; 3492 + req.format_id = TX_POWER_LIMIT_ENABLE; 3493 + 3494 + ret = mt76_mcu_send_msg(&dev->mt76, 3495 + MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req, 3496 + sizeof(req), true); 3497 + if (ret) 3498 + return ret; 3499 + 3500 + req.sku_enable = phy->sku_path_en; 3501 + req.format_id = TX_POWER_LIMIT_PATH_ENABLE; 3582 3502 3583 3503 return mt76_mcu_send_msg(&dev->mt76, 3584 3504 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
+7 -1
drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7915_MCU_H ··· 429 429 430 430 enum { 431 431 TX_POWER_LIMIT_ENABLE, 432 + TX_POWER_LIMIT_PATH_ENABLE = 0x3, 432 433 TX_POWER_LIMIT_TABLE = 0x4, 433 434 TX_POWER_LIMIT_INFO = 0x7, 434 435 TX_POWER_LIMIT_FRAME = 0x11, 435 436 TX_POWER_LIMIT_FRAME_MIN = 0x12, 437 + }; 438 + 439 + enum { 440 + TX_POWER_INFO_PATH = 1, 441 + TX_POWER_INFO_RATE, 436 442 }; 437 443 438 444 enum {
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/mmio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/kernel.h>
+8 -3
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7915_H ··· 70 70 #define MT7915_CDEV_THROTTLE_MAX 99 71 71 72 72 #define MT7915_SKU_RATE_NUM 161 73 + #define MT7915_SKU_PATH_NUM 185 73 74 74 75 #define MT7915_MAX_TWT_AGRT 16 75 76 #define MT7915_MAX_STA_TWT_AGRT 8 ··· 223 222 224 223 struct mt76_mib_stats mib; 225 224 struct mt76_channel_state state_ts; 225 + 226 + bool sku_limit_en:1; 227 + bool sku_path_en:1; 226 228 227 229 #ifdef CONFIG_NL80211_TESTMODE 228 230 struct { ··· 495 491 int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, 496 492 u8 en); 497 493 int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band); 498 - int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable); 494 + int mt7915_mcu_set_sku_en(struct mt7915_phy *phy); 499 495 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy); 500 - int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len); 496 + int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len, 497 + u8 category); 501 498 int mt7915_mcu_set_txpower_frame_min(struct mt7915_phy *phy, s8 txpower); 502 499 int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy, 503 500 struct ieee80211_vif *vif,
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7915_REGS_H
+9 -14
drivers/net/wireless/mediatek/mt76/mt7915/soc.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2022 MediaTek Inc. */ 3 3 4 4 #include <linux/kernel.h> ··· 284 284 static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev) 285 285 { 286 286 struct device *pdev = dev->mt76.dev; 287 - struct reserved_mem *rmem; 288 - struct device_node *np; 287 + struct resource res; 289 288 u32 val; 289 + int ret; 290 290 291 - np = of_parse_phandle(pdev->of_node, "memory-region", 0); 292 - if (!np) 293 - return -EINVAL; 291 + ret = of_reserved_mem_region_to_resource(pdev->of_node, 0, &res); 292 + if (ret) 293 + return ret; 294 294 295 - rmem = of_reserved_mem_lookup(np); 296 - of_node_put(np); 297 - if (!rmem) 298 - return -EINVAL; 299 - 300 - val = (rmem->base >> 16) & MT_TOP_MCU_EMI_BASE_MASK; 295 + val = (res.start >> 16) & MT_TOP_MCU_EMI_BASE_MASK; 301 296 302 297 if (is_mt7986(&dev->mt76)) { 303 298 /* Set conninfra subsys PLL check */ ··· 313 318 MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16); 314 319 } 315 320 316 - mt76_wr(dev, MT_INFRA_BUS_EMI_START, rmem->base); 317 - mt76_wr(dev, MT_INFRA_BUS_EMI_END, rmem->size); 321 + mt76_wr(dev, MT_INFRA_BUS_EMI_START, res.start); 322 + mt76_wr(dev, MT_INFRA_BUS_EMI_END, resource_size(&res)); 318 323 319 324 mt76_rr(dev, MT_CONN_INFRA_EFUSE); 320 325
+2 -2
drivers/net/wireless/mediatek/mt76/mt7915/testmode.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include "mt7915.h" ··· 409 409 if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) 410 410 return; 411 411 412 - mt7915_mcu_set_sku_en(phy, !en); 412 + mt7915_mcu_set_sku_en(phy); 413 413 414 414 mt7915_tm_mode_ctrl(dev, en); 415 415 mt7915_tm_reg_backup_restore(phy);
+1 -1
drivers/net/wireless/mediatek/mt76/mt7915/testmode.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7915_TESTMODE_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/Kconfig
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT7921_COMMON 3 3 tristate 4 4 select MT792x_LIB
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/Makefile
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 obj-$(CONFIG_MT7921_COMMON) += mt7921-common.o 4 4 obj-$(CONFIG_MT7921E) += mt7921e.o
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include "mt7921.h"
+2 -2
drivers/net/wireless/mediatek/mt76/mt7921/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h> ··· 343 343 dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask; 344 344 dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask; 345 345 346 - queue_work(system_wq, &dev->init_work); 346 + queue_work(system_percpu_wq, &dev->init_work); 347 347 348 348 return 0; 349 349 }
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/devcoredump.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h>
+2 -2
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #include <linux/fs.h> ··· 646 646 if (err) 647 647 return err; 648 648 649 - set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 650 649 err = mt7921_load_clc(dev, mt792x_ram_name(dev)); 651 650 if (err) 652 651 return err; 652 + set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 653 653 654 654 return mt7921_mcu_fw_log_2_host(dev, 1); 655 655 }
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7921_MCU_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7921_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2021 MediaTek Inc. */ 3 3 4 4 #include "mt7921.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2021 MediaTek Inc. */ 3 3 4 4 #include "mt7921.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7921_REGS_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2021 MediaTek Inc. 3 3 * 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2021 MediaTek Inc. */ 3 3 4 4 #include <linux/iopoll.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2021 MediaTek Inc. */ 3 3 4 4 #include <linux/kernel.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/testmode.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7921.h" 4 4 #include "mcu.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7921/usb.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2022 MediaTek Inc. 3 3 * 4 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/Kconfig
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT7925_COMMON 3 3 tristate 4 4 select MT792x_LIB
+2 -2
drivers/net/wireless/mediatek/mt76/mt7925/Makefile
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 obj-$(CONFIG_MT7925_COMMON) += mt7925-common.o 4 4 obj-$(CONFIG_MT7925E) += mt7925e.o 5 5 obj-$(CONFIG_MT7925U) += mt7925u.o 6 6 7 - mt7925-common-y := mac.o mcu.o main.o init.o debugfs.o 7 + mt7925-common-y := mac.o mcu.o regd.o main.o init.o debugfs.o 8 8 mt7925-common-$(CONFIG_NL80211_TESTMODE) += testmode.o 9 9 mt7925e-y := pci.o pci_mac.o pci_mcu.o 10 10 mt7925u-y := usb.o
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include "mt7925.h"
+3 -149
drivers/net/wireless/mediatek/mt76/mt7925/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h> ··· 7 7 #include <linux/thermal.h> 8 8 #include <linux/firmware.h> 9 9 #include "mt7925.h" 10 + #include "regd.h" 10 11 #include "mac.h" 11 12 #include "mcu.h" 12 13 ··· 61 60 return PTR_ERR_OR_ZERO(hwmon); 62 61 } 63 62 64 - void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2) 65 - { 66 - struct mt792x_phy *phy = &dev->phy; 67 - struct mt7925_clc_rule_v2 *rule; 68 - struct mt7925_clc *clc; 69 - bool old = dev->has_eht, new = true; 70 - u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2); 71 - u8 *pos; 72 - 73 - if (mtcl_conf != MT792X_ACPI_MTCL_INVALID && 74 - (((mtcl_conf >> 4) & 0x3) == 0)) { 75 - new = false; 76 - goto out; 77 - } 78 - 79 - if (!phy->clc[MT792x_CLC_BE_CTRL]) 80 - goto out; 81 - 82 - clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL]; 83 - pos = clc->data; 84 - 85 - while (1) { 86 - rule = (struct mt7925_clc_rule_v2 *)pos; 87 - 88 - if (rule->alpha2[0] == alpha2[0] && 89 - rule->alpha2[1] == alpha2[1]) { 90 - new = false; 91 - break; 92 - } 93 - 94 - /* Check the last one */ 95 - if (rule->flag & BIT(0)) 96 - break; 97 - 98 - pos += sizeof(*rule); 99 - } 100 - 101 - out: 102 - if (old == new) 103 - return; 104 - 105 - dev->has_eht = new; 106 - mt7925_set_stream_he_eht_caps(phy); 107 - } 108 - 109 - static void 110 - mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) 111 - { 112 - #define IS_UNII_INVALID(idx, sfreq, efreq, cfreq) \ 113 - (!(dev->phy.clc_chan_conf & BIT(idx)) && (cfreq) >= (sfreq) && (cfreq) <= (efreq)) 114 - #define MT7925_UNII_59G_IS_VALID 0x1 115 - #define MT7925_UNII_6G_IS_VALID 0x1e 116 - struct ieee80211_supported_band *sband; 117 - struct mt76_dev *mdev = &dev->mt76; 118 - struct ieee80211_channel *ch; 119 - u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, mdev->alpha2); 120 - int i; 121 - 122 - if (mtcl_conf != MT792X_ACPI_MTCL_INVALID) { 123 - if ((mtcl_conf & 0x3) == 0) 124 - dev->phy.clc_chan_conf &= ~MT7925_UNII_59G_IS_VALID; 125 - if (((mtcl_conf >> 2) & 0x3) == 0) 126 - dev->phy.clc_chan_conf &= ~MT7925_UNII_6G_IS_VALID; 127 - } 128 - 129 - sband = wiphy->bands[NL80211_BAND_5GHZ]; 130 - if (!sband) 131 - return; 132 - 133 - for (i = 0; i < sband->n_channels; i++) { 134 - ch = &sband->channels[i]; 135 - 136 - /* UNII-4 */ 137 - if (IS_UNII_INVALID(0, 5845, 5925, ch->center_freq)) 138 - ch->flags |= IEEE80211_CHAN_DISABLED; 139 - } 140 - 141 - sband = wiphy->bands[NL80211_BAND_6GHZ]; 142 - if (!sband) 143 - return; 144 - 145 - for (i = 0; i < sband->n_channels; i++) { 146 - ch = &sband->channels[i]; 147 - 148 - /* UNII-5/6/7/8 */ 149 - if (IS_UNII_INVALID(1, 5925, 6425, ch->center_freq) || 150 - IS_UNII_INVALID(2, 6425, 6525, ch->center_freq) || 151 - IS_UNII_INVALID(3, 6525, 6875, ch->center_freq) || 152 - IS_UNII_INVALID(4, 6875, 7125, ch->center_freq)) 153 - ch->flags |= IEEE80211_CHAN_DISABLED; 154 - } 155 - } 156 - 157 - void mt7925_regd_update(struct mt792x_dev *dev) 158 - { 159 - struct mt76_dev *mdev = &dev->mt76; 160 - struct ieee80211_hw *hw = mdev->hw; 161 - struct wiphy *wiphy = hw->wiphy; 162 - 163 - if (!dev->regd_change) 164 - return; 165 - 166 - mt7925_mcu_set_clc(dev, mdev->alpha2, dev->country_ie_env); 167 - mt7925_regd_channel_update(wiphy, dev); 168 - mt7925_mcu_set_channel_domain(hw->priv); 169 - mt7925_set_tx_sar_pwr(hw, NULL); 170 - dev->regd_change = false; 171 - } 172 - EXPORT_SYMBOL_GPL(mt7925_regd_update); 173 - 174 - static void 175 - mt7925_regd_notifier(struct wiphy *wiphy, 176 - struct regulatory_request *req) 177 - { 178 - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 179 - struct mt792x_dev *dev = mt792x_hw_dev(hw); 180 - struct mt76_dev *mdev = &dev->mt76; 181 - struct mt76_connac_pm *pm = &dev->pm; 182 - 183 - /* allow world regdom at the first boot only */ 184 - if (!memcmp(req->alpha2, "00", 2) && 185 - mdev->alpha2[0] && mdev->alpha2[1]) 186 - return; 187 - 188 - /* do not need to update the same country twice */ 189 - if (!memcmp(req->alpha2, mdev->alpha2, 2) && 190 - dev->country_ie_env == req->country_ie_env) 191 - return; 192 - 193 - memcpy(mdev->alpha2, req->alpha2, 2); 194 - mdev->region = req->dfs_region; 195 - dev->country_ie_env = req->country_ie_env; 196 - dev->regd_change = true; 197 - 198 - if (pm->suspended) 199 - return; 200 - 201 - dev->regd_in_progress = true; 202 - mt792x_mutex_acquire(dev); 203 - mt7925_regd_update(dev); 204 - mt792x_mutex_release(dev); 205 - dev->regd_in_progress = false; 206 - wake_up(&dev->wait); 207 - } 208 - 209 63 static void mt7925_mac_init_basic_rates(struct mt792x_dev *dev) 210 64 { 211 65 int i; ··· 90 234 mt792x_mac_init_band(dev, i); 91 235 92 236 mt7925_mac_init_basic_rates(dev); 93 - 94 - memzero_explicit(&dev->mt76.alpha2, sizeof(dev->mt76.alpha2)); 95 237 96 238 return 0; 97 239 } ··· 274 420 dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask; 275 421 dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask; 276 422 277 - queue_work(system_wq, &dev->init_work); 423 + queue_work(system_percpu_wq, &dev->init_work); 278 424 279 425 return 0; 280 426 }
+3 -4
drivers/net/wireless/mediatek/mt76/mt7925/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/devcoredump.h> ··· 6 6 #include <linux/timekeeping.h> 7 7 #include "mt7925.h" 8 8 #include "../dma.h" 9 + #include "regd.h" 9 10 #include "mac.h" 10 11 #include "mcu.h" 11 12 ··· 1330 1329 mt7925_vif_connect_iter, NULL); 1331 1330 mt76_connac_power_save_sched(&dev->mt76.phy, pm); 1332 1331 1333 - mt792x_mutex_acquire(dev); 1334 - mt7925_mcu_set_clc(dev, "00", ENVIRON_INDOOR); 1335 - mt792x_mutex_release(dev); 1332 + mt7925_regd_change(&dev->phy, "00"); 1336 1333 } 1337 1334 1338 1335 void mt7925_coredump_work(struct work_struct *work)
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7925_MAC_H
+14 -26
drivers/net/wireless/mediatek/mt76/mt7925/main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/etherdevice.h> ··· 8 8 #include <linux/ctype.h> 9 9 #include <net/ipv6.h> 10 10 #include "mt7925.h" 11 + #include "regd.h" 11 12 #include "mcu.h" 12 13 #include "mac.h" 13 14 ··· 139 138 } 140 139 141 140 if (band == NL80211_BAND_6GHZ) { 141 + struct ieee80211_supported_band *sband = 142 + &phy->mt76->sband_5g.sband; 143 + struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; 144 + 142 145 u16 cap = IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS | 143 146 IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS; 144 147 145 - cap |= u16_encode_bits(IEEE80211_HT_MPDU_DENSITY_0_5, 148 + cap |= u16_encode_bits(ht_cap->ampdu_density, 146 149 IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START) | 147 150 u16_encode_bits(IEEE80211_VHT_MAX_AMPDU_1024K, 148 151 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP) | ··· 435 430 goto out; 436 431 437 432 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; 433 + if (phy->chip_cap & MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN) 434 + vif->driver_flags |= IEEE80211_VIF_SUPPORTS_CQM_RSSI; 435 + 438 436 out: 439 437 mt792x_mutex_release(dev); 440 438 ··· 1320 1312 mt7925_mlo_pm_iter, dev); 1321 1313 } 1322 1314 1323 - static bool is_valid_alpha2(const char *alpha2) 1324 - { 1325 - if (!alpha2) 1326 - return false; 1327 - 1328 - if (alpha2[0] == '0' && alpha2[1] == '0') 1329 - return true; 1330 - 1331 - if (isalpha(alpha2[0]) && isalpha(alpha2[1])) 1332 - return true; 1333 - 1334 - return false; 1335 - } 1336 - 1337 1315 void mt7925_scan_work(struct work_struct *work) 1338 1316 { 1339 1317 struct mt792x_phy *phy; ··· 1328 1334 scan_work.work); 1329 1335 1330 1336 while (true) { 1331 - struct mt76_dev *mdev = &phy->dev->mt76; 1332 1337 struct sk_buff *skb; 1333 1338 struct tlv *tlv; 1334 1339 int tlv_len; ··· 1358 1365 case UNI_EVENT_SCAN_DONE_CHNLINFO: 1359 1366 evt = (struct mt7925_mcu_scan_chinfo_event *)tlv->data; 1360 1367 1361 - if (!is_valid_alpha2(evt->alpha2)) 1362 - break; 1363 - 1364 - mt7925_regd_be_ctrl(phy->dev, evt->alpha2); 1365 - 1366 - if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') 1367 - break; 1368 - 1369 - mt7925_mcu_set_clc(phy->dev, evt->alpha2, ENVIRON_INDOOR); 1368 + mt7925_regd_change(phy, evt->alpha2); 1370 1369 1371 1370 break; 1372 1371 case UNI_EVENT_SCAN_DONE_NLO: ··· 1942 1957 if (changed & IEEE80211_CHANCTX_CHANGE_PUNCTURING) 1943 1958 mt7925_mcu_set_eht_pp(mvif->phy->mt76, &mconf->mt76, 1944 1959 link_conf, NULL); 1960 + 1961 + if (changed & BSS_CHANGED_CQM) 1962 + mt7925_mcu_set_rssimonitor(dev, vif); 1945 1963 1946 1964 mt792x_mutex_release(dev); 1947 1965 }
+91 -8
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/fs.h> 5 5 #include <linux/firmware.h> 6 6 #include "mt7925.h" 7 + #include "regd.h" 7 8 #include "mcu.h" 8 9 #include "mac.h" 9 10 10 11 #define MT_STA_BFER BIT(0) 11 12 #define MT_STA_BFEE BIT(1) 12 - 13 - static bool mt7925_disable_clc; 14 - module_param_named(disable_clc, mt7925_disable_clc, bool, 0644); 15 - MODULE_PARM_DESC(disable_clc, "disable CLC support"); 16 13 17 14 int mt7925_mcu_parse_response(struct mt76_dev *mdev, int cmd, 18 15 struct sk_buff *skb, int seq) ··· 448 451 } 449 452 450 453 static void 454 + mt7925_mcu_rssi_monitor_iter(void *priv, u8 *mac, 455 + struct ieee80211_vif *vif) 456 + { 457 + struct mt7925_uni_rssi_monitor_event *event = priv; 458 + enum nl80211_cqm_rssi_threshold_event nl_event; 459 + s32 rssi = le32_to_cpu(event->rssi); 460 + 461 + if (vif->type != NL80211_IFTYPE_STATION) 462 + return; 463 + 464 + if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) 465 + return; 466 + 467 + if (rssi > vif->bss_conf.cqm_rssi_thold) 468 + nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; 469 + else 470 + nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; 471 + 472 + ieee80211_cqm_rssi_notify(vif, nl_event, rssi, GFP_KERNEL); 473 + } 474 + 475 + static void 476 + mt7925_mcu_rssi_monitor_event(struct mt792x_dev *dev, struct sk_buff *skb) 477 + { 478 + struct tlv *tlv; 479 + u32 tlv_len; 480 + struct mt7925_uni_rssi_monitor_event *event; 481 + 482 + skb_pull(skb, sizeof(struct mt7925_mcu_rxd) + 4); 483 + tlv = (struct tlv *)skb->data; 484 + tlv_len = skb->len; 485 + 486 + while (tlv_len > 0 && le16_to_cpu(tlv->len) <= tlv_len) { 487 + switch (le16_to_cpu(tlv->tag)) { 488 + case UNI_EVENT_RSSI_MONITOR_INFO: 489 + event = (struct mt7925_uni_rssi_monitor_event *)skb->data; 490 + ieee80211_iterate_active_interfaces_atomic(dev->mt76.hw, 491 + IEEE80211_IFACE_ITER_RESUME_ALL, 492 + mt7925_mcu_rssi_monitor_iter, 493 + event); 494 + break; 495 + default: 496 + break; 497 + } 498 + tlv_len -= le16_to_cpu(tlv->len); 499 + tlv = (struct tlv *)((char *)(tlv) + le16_to_cpu(tlv->len)); 500 + } 501 + } 502 + 503 + static void 451 504 mt7925_mcu_uni_debug_msg_event(struct mt792x_dev *dev, struct sk_buff *skb) 452 505 { 453 506 struct mt7925_uni_debug_msg { ··· 592 545 break; 593 546 case MCU_UNI_EVENT_BSS_BEACON_LOSS: 594 547 mt7925_mcu_connection_loss_event(dev, skb); 548 + break; 549 + case MCU_UNI_EVENT_RSSI_MONITOR: 550 + mt7925_mcu_rssi_monitor_event(dev, skb); 595 551 break; 596 552 case MCU_UNI_EVENT_COREDUMP: 597 553 dev->fw_assert = true; ··· 738 688 int ret, i, len, offset = 0; 739 689 740 690 dev->phy.clc_chan_conf = 0xff; 741 - if (mt7925_disable_clc || 742 - mt76_is_usb(&dev->mt76)) 691 + dev->regd_user = false; 692 + if (!mt7925_regd_clc_supported(dev)) 743 693 return 0; 744 694 745 695 if (mt76_is_mmio(&dev->mt76)) { ··· 809 759 } 810 760 } 811 761 762 + ret = mt7925_regd_init(phy); 812 763 out: 813 764 release_firmware(fw); 814 765 ··· 1054 1003 if (err) 1055 1004 return err; 1056 1005 1057 - set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 1058 1006 err = mt7925_load_clc(dev, mt792x_ram_name(dev)); 1059 1007 if (err) 1060 1008 return err; 1009 + set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 1061 1010 1062 1011 return mt7925_mcu_fw_log_2_host(dev, 1); 1063 1012 } ··· 3434 3383 struct mt792x_phy *phy = (struct mt792x_phy *)&dev->phy; 3435 3384 int i, ret; 3436 3385 3386 + if (!ARRAY_SIZE(phy->clc)) 3387 + return -ESRCH; 3388 + 3437 3389 /* submit all clc config */ 3438 3390 for (i = 0; i < ARRAY_SIZE(phy->clc); i++) { 3439 3391 if (i == MT792x_CLC_BE_CTRL) ··· 3871 3817 3872 3818 return mt76_mcu_send_msg(&phy->dev->mt76, MCU_UNI_CMD(BAND_CONFIG), 3873 3819 &req, sizeof(req), true); 3820 + } 3821 + 3822 + int mt7925_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif) 3823 + { 3824 + struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(&vif->bss_conf); 3825 + struct { 3826 + struct { 3827 + u8 bss_idx; 3828 + u8 pad[3]; 3829 + } __packed hdr; 3830 + __le16 tag; 3831 + __le16 len; 3832 + u8 enable; 3833 + s8 cqm_rssi_high; 3834 + s8 cqm_rssi_low; 3835 + u8 rsv; 3836 + } req = { 3837 + .hdr = { 3838 + .bss_idx = mconf->mt76.idx, 3839 + }, 3840 + .tag = cpu_to_le16(UNI_CMD_RSSI_MONITOR_SET), 3841 + .len = cpu_to_le16(sizeof(req) - 4), 3842 + .enable = vif->cfg.assoc, 3843 + .cqm_rssi_high = (s8)(vif->bss_conf.cqm_rssi_thold + vif->bss_conf.cqm_rssi_hyst), 3844 + .cqm_rssi_low = (s8)(vif->bss_conf.cqm_rssi_thold - vif->bss_conf.cqm_rssi_hyst), 3845 + }; 3846 + 3847 + return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(RSSI_MONITOR), &req, 3848 + sizeof(req), false); 3874 3849 }
+9 -1
drivers/net/wireless/mediatek/mt76/mt7925/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7925_MCU_H ··· 150 150 UNI_EVENT_SCAN_DONE_BASIC = 0, 151 151 UNI_EVENT_SCAN_DONE_CHNLINFO = 2, 152 152 UNI_EVENT_SCAN_DONE_NLO = 3, 153 + }; 154 + 155 + enum { 156 + UNI_CMD_RSSI_MONITOR_SET = 0, 157 + }; 158 + 159 + enum { 160 + UNI_EVENT_RSSI_MONITOR_INFO = 0, 153 161 }; 154 162 155 163 enum connac3_mcu_cipher_type {
+8 -3
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7925_H ··· 101 101 u8 pad[3]; 102 102 } __packed hdr; 103 103 struct mt7925_beacon_loss_tlv beacon_loss; 104 + } __packed; 105 + 106 + struct mt7925_uni_rssi_monitor_event { 107 + __le16 tag; 108 + __le16 len; 109 + __le32 rssi; 104 110 } __packed; 105 111 106 112 #define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2) ··· 263 257 int mt7925_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif, 264 258 u8 bit_op, u32 bit_map); 265 259 266 - void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); 267 - void mt7925_regd_update(struct mt792x_dev *dev); 268 260 int mt7925_mac_init(struct mt792x_dev *dev); 269 261 int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, 270 262 struct ieee80211_sta *sta); ··· 376 372 int mt7925_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, 377 373 struct netlink_callback *cb, void *data, int len); 378 374 375 + int mt7925_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif); 379 376 #endif
+3 -2
drivers/net/wireless/mediatek/mt76/mt7925/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/kernel.h> ··· 8 8 #include "mt7925.h" 9 9 #include "mac.h" 10 10 #include "mcu.h" 11 + #include "regd.h" 11 12 #include "../dma.h" 12 13 13 14 static const struct pci_device_id mt7925_pci_device_table[] = { ··· 585 584 if (!pm->ds_enable) 586 585 mt7925_mcu_set_deep_sleep(dev, false); 587 586 588 - mt7925_regd_update(dev); 587 + mt7925_mcu_regd_update(dev, mdev->alpha2, dev->country_ie_env); 589 588 failed: 590 589 pm->suspended = false; 591 590
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/pci_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include "mt7925.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/pci_mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include "mt7925.h"
+265
drivers/net/wireless/mediatek/mt76/mt7925/regd.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 + /* Copyright (C) 2025 MediaTek Inc. */ 3 + 4 + #include "mt7925.h" 5 + #include "regd.h" 6 + #include "mcu.h" 7 + 8 + static bool mt7925_disable_clc; 9 + module_param_named(disable_clc, mt7925_disable_clc, bool, 0644); 10 + MODULE_PARM_DESC(disable_clc, "disable CLC support"); 11 + 12 + bool mt7925_regd_clc_supported(struct mt792x_dev *dev) 13 + { 14 + if (mt7925_disable_clc || 15 + mt76_is_usb(&dev->mt76)) 16 + return false; 17 + 18 + return true; 19 + } 20 + 21 + void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2) 22 + { 23 + struct mt792x_phy *phy = &dev->phy; 24 + struct mt7925_clc_rule_v2 *rule; 25 + struct mt7925_clc *clc; 26 + bool old = dev->has_eht, new = true; 27 + u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2); 28 + u8 *pos; 29 + 30 + if (mtcl_conf != MT792X_ACPI_MTCL_INVALID && 31 + (((mtcl_conf >> 4) & 0x3) == 0)) { 32 + new = false; 33 + goto out; 34 + } 35 + 36 + if (!phy->clc[MT792x_CLC_BE_CTRL]) 37 + goto out; 38 + 39 + clc = (struct mt7925_clc *)phy->clc[MT792x_CLC_BE_CTRL]; 40 + pos = clc->data; 41 + 42 + while (1) { 43 + rule = (struct mt7925_clc_rule_v2 *)pos; 44 + 45 + if (rule->alpha2[0] == alpha2[0] && 46 + rule->alpha2[1] == alpha2[1]) { 47 + new = false; 48 + break; 49 + } 50 + 51 + /* Check the last one */ 52 + if (rule->flag & BIT(0)) 53 + break; 54 + 55 + pos += sizeof(*rule); 56 + } 57 + 58 + out: 59 + if (old == new) 60 + return; 61 + 62 + dev->has_eht = new; 63 + mt7925_set_stream_he_eht_caps(phy); 64 + } 65 + 66 + static void 67 + mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev) 68 + { 69 + #define IS_UNII_INVALID(idx, sfreq, efreq, cfreq) \ 70 + (!(dev->phy.clc_chan_conf & BIT(idx)) && (cfreq) >= (sfreq) && (cfreq) <= (efreq)) 71 + #define MT7925_UNII_59G_IS_VALID 0x1 72 + #define MT7925_UNII_6G_IS_VALID 0x1e 73 + struct ieee80211_supported_band *sband; 74 + struct mt76_dev *mdev = &dev->mt76; 75 + struct ieee80211_channel *ch; 76 + u32 mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, mdev->alpha2); 77 + int i; 78 + 79 + if (mtcl_conf != MT792X_ACPI_MTCL_INVALID) { 80 + if ((mtcl_conf & 0x3) == 0) 81 + dev->phy.clc_chan_conf &= ~MT7925_UNII_59G_IS_VALID; 82 + if (((mtcl_conf >> 2) & 0x3) == 0) 83 + dev->phy.clc_chan_conf &= ~MT7925_UNII_6G_IS_VALID; 84 + } 85 + 86 + sband = wiphy->bands[NL80211_BAND_2GHZ]; 87 + if (!sband) 88 + return; 89 + 90 + for (i = 0; i < sband->n_channels; i++) { 91 + ch = &sband->channels[i]; 92 + 93 + if (!dev->has_eht) 94 + ch->flags |= IEEE80211_CHAN_NO_EHT; 95 + } 96 + 97 + sband = wiphy->bands[NL80211_BAND_5GHZ]; 98 + if (!sband) 99 + return; 100 + 101 + for (i = 0; i < sband->n_channels; i++) { 102 + ch = &sband->channels[i]; 103 + 104 + /* UNII-4 */ 105 + if (IS_UNII_INVALID(0, 5845, 5925, ch->center_freq)) 106 + ch->flags |= IEEE80211_CHAN_DISABLED; 107 + 108 + if (!dev->has_eht) 109 + ch->flags |= IEEE80211_CHAN_NO_EHT; 110 + } 111 + 112 + sband = wiphy->bands[NL80211_BAND_6GHZ]; 113 + if (!sband) 114 + return; 115 + 116 + for (i = 0; i < sband->n_channels; i++) { 117 + ch = &sband->channels[i]; 118 + 119 + /* UNII-5/6/7/8 */ 120 + if (IS_UNII_INVALID(1, 5925, 6425, ch->center_freq) || 121 + IS_UNII_INVALID(2, 6425, 6525, ch->center_freq) || 122 + IS_UNII_INVALID(3, 6525, 6875, ch->center_freq) || 123 + IS_UNII_INVALID(4, 6875, 7125, ch->center_freq)) 124 + ch->flags |= IEEE80211_CHAN_DISABLED; 125 + 126 + if (!dev->has_eht) 127 + ch->flags |= IEEE80211_CHAN_NO_EHT; 128 + } 129 + } 130 + 131 + int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2, 132 + enum environment_cap country_ie_env) 133 + { 134 + struct ieee80211_hw *hw = mt76_hw(dev); 135 + struct wiphy *wiphy = hw->wiphy; 136 + int ret = 0; 137 + 138 + dev->regd_in_progress = true; 139 + 140 + mt792x_mutex_acquire(dev); 141 + if (!dev->regd_change) 142 + goto err; 143 + 144 + ret = mt7925_mcu_set_clc(dev, alpha2, country_ie_env); 145 + if (ret < 0) 146 + goto err; 147 + 148 + mt7925_regd_be_ctrl(dev, alpha2); 149 + mt7925_regd_channel_update(wiphy, dev); 150 + 151 + ret = mt7925_mcu_set_channel_domain(hw->priv); 152 + if (ret < 0) 153 + goto err; 154 + 155 + ret = mt7925_set_tx_sar_pwr(hw, NULL); 156 + if (ret < 0) 157 + goto err; 158 + 159 + err: 160 + mt792x_mutex_release(dev); 161 + dev->regd_change = false; 162 + dev->regd_in_progress = false; 163 + wake_up(&dev->wait); 164 + 165 + return ret; 166 + } 167 + EXPORT_SYMBOL_GPL(mt7925_mcu_regd_update); 168 + 169 + void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req) 170 + { 171 + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 172 + struct mt792x_dev *dev = mt792x_hw_dev(hw); 173 + struct mt76_connac_pm *pm = &dev->pm; 174 + struct mt76_dev *mdev = &dev->mt76; 175 + 176 + if (req->initiator == NL80211_REGDOM_SET_BY_USER && 177 + !dev->regd_user) 178 + dev->regd_user = true; 179 + 180 + /* allow world regdom at the first boot only */ 181 + if (!memcmp(req->alpha2, "00", 2) && 182 + mdev->alpha2[0] && mdev->alpha2[1]) 183 + return; 184 + 185 + /* do not need to update the same country twice */ 186 + if (!memcmp(req->alpha2, mdev->alpha2, 2) && 187 + dev->country_ie_env == req->country_ie_env) 188 + return; 189 + 190 + memcpy(mdev->alpha2, req->alpha2, 2); 191 + mdev->region = req->dfs_region; 192 + dev->country_ie_env = req->country_ie_env; 193 + 194 + dev->regd_change = true; 195 + 196 + if (pm->suspended) 197 + /* postpone the mcu update to resume */ 198 + return; 199 + 200 + mt7925_mcu_regd_update(dev, req->alpha2, 201 + req->country_ie_env); 202 + return; 203 + } 204 + 205 + static bool 206 + mt7925_regd_is_valid_alpha2(const char *alpha2) 207 + { 208 + if (!alpha2) 209 + return false; 210 + 211 + if (alpha2[0] == '0' && alpha2[1] == '0') 212 + return true; 213 + 214 + if (isalpha(alpha2[0]) && isalpha(alpha2[1])) 215 + return true; 216 + 217 + return false; 218 + } 219 + 220 + int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2) 221 + { 222 + struct wiphy *wiphy = phy->mt76->hw->wiphy; 223 + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 224 + struct mt792x_dev *dev = mt792x_hw_dev(hw); 225 + struct mt76_dev *mdev = &dev->mt76; 226 + 227 + if (dev->hw_full_reset) 228 + return 0; 229 + 230 + if (!mt7925_regd_is_valid_alpha2(alpha2) || 231 + !mt7925_regd_clc_supported(dev) || 232 + dev->regd_user) 233 + return -EINVAL; 234 + 235 + if (mdev->alpha2[0] != '0' && mdev->alpha2[1] != '0') 236 + return 0; 237 + 238 + /* do not need to update the same country twice */ 239 + if (!memcmp(alpha2, mdev->alpha2, 2)) 240 + return 0; 241 + 242 + if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) { 243 + return regulatory_hint(wiphy, alpha2); 244 + } else { 245 + return mt7925_mcu_set_clc(dev, alpha2, ENVIRON_INDOOR); 246 + } 247 + } 248 + EXPORT_SYMBOL_GPL(mt7925_regd_change); 249 + 250 + int mt7925_regd_init(struct mt792x_phy *phy) 251 + { 252 + struct wiphy *wiphy = phy->mt76->hw->wiphy; 253 + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 254 + struct mt792x_dev *dev = mt792x_hw_dev(hw); 255 + struct mt76_dev *mdev = &dev->mt76; 256 + 257 + if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) { 258 + wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE | 259 + REGULATORY_DISABLE_BEACON_HINTS; 260 + } else { 261 + memzero_explicit(&mdev->alpha2, sizeof(mdev->alpha2)); 262 + } 263 + 264 + return 0; 265 + }
+19
drivers/net/wireless/mediatek/mt76/mt7925/regd.h
··· 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 + /* Copyright (C) 2025 MediaTek Inc. */ 3 + 4 + #ifndef __MT7925_REGD_H 5 + #define __MT7925_REGD_H 6 + 7 + #include "mt7925.h" 8 + 9 + int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2, 10 + enum environment_cap country_ie_env); 11 + 12 + void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2); 13 + void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req); 14 + bool mt7925_regd_clc_supported(struct mt792x_dev *dev); 15 + int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2); 16 + int mt7925_regd_init(struct mt792x_phy *phy); 17 + 18 + #endif 19 +
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7925_REGS_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/testmode.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 #include "mt7925.h" 4 4 #include "mcu.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt7925/usb.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/kernel.h>
+3 -1
drivers/net/wireless/mediatek/mt76/mt792x.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT792X_H ··· 28 28 #define MT792x_CHIP_CAP_CLC_EVT_EN BIT(0) 29 29 #define MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN BIT(1) 30 30 #define MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN BIT(3) 31 + #define MT792x_CHIP_CAP_11D_EN BIT(4) 31 32 #define MT792x_CHIP_CAP_MLO_EN BIT(8) 32 33 #define MT792x_CHIP_CAP_MLO_EML_EN BIT(9) 33 34 ··· 231 230 bool hw_init_done:1; 232 231 bool fw_assert:1; 233 232 bool has_eht:1; 233 + bool regd_user:1; 234 234 bool regd_in_progress:1; 235 235 bool aspm_supported:1; 236 236 bool hif_idle:1;
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/acpi.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT7921_ACPI_SAR_H
+1 -2
drivers/net/wireless/mediatek/mt76/mt792x_core.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/module.h> ··· 688 688 ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); 689 689 ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); 690 690 ieee80211_hw_set(hw, CONNECTION_MONITOR); 691 - ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR); 692 691 ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); 693 692 ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); 694 693
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include "mt792x.h"
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_dma.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/module.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/module.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef __MT792X_REGS_H
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_trace.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2023 Lorenzo Bianconi <lorenzo@kernel.org> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_trace.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2023 Lorenzo Bianconi <lorenzo@kernel.org> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt792x_usb.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. 3 3 * 4 4 * Author: Lorenzo Bianconi <lorenzo@kernel.org>
+8 -1
drivers/net/wireless/mediatek/mt76/mt7996/Kconfig
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 config MT7996E 3 3 tristate "MediaTek MT7996 (PCIe) support" 4 4 select MT76_CONNAC_LIB ··· 12 12 and 2.4GHz IEEE 802.11be 4x4:4SS 4096-QAM, 320MHz channels. 13 13 14 14 To compile this driver as a module, choose M here. 15 + 16 + config MT7996_NPU 17 + bool "MT7996 (PCIe) NPU support" 18 + depends on MT7996E 19 + depends on NET_AIROHA_NPU=y || MT7996E=NET_AIROHA_NPU 20 + select MT76_NPU 21 + default n
+2 -1
drivers/net/wireless/mediatek/mt76/mt7996/Makefile
··· 1 - # SPDX-License-Identifier: ISC 1 + # SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 3 3 obj-$(CONFIG_MT7996E) += mt7996e.o 4 4 5 5 mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \ 6 6 debugfs.o mmio.o 7 7 8 + mt7996e-$(CONFIG_MT7996_NPU) += npu.o 8 9 mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/coredump.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #include <linux/devcoredump.h>
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/coredump.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2023 MediaTek Inc. */ 3 3 4 4 #ifndef _COREDUMP_H_
+45 -29
drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 953 953 #ifdef CONFIG_MAC80211_DEBUGFS 954 954 /** per-station debugfs **/ 955 955 956 - static ssize_t mt7996_sta_fixed_rate_set(struct file *file, 957 - const char __user *user_buf, 958 - size_t count, loff_t *ppos) 956 + static int 957 + mt7996_queues_show(struct seq_file *s, void *data) 958 + { 959 + struct ieee80211_sta *sta = s->private; 960 + 961 + mt7996_sta_hw_queue_read(s, sta); 962 + 963 + return 0; 964 + } 965 + 966 + DEFINE_SHOW_ATTRIBUTE(mt7996_queues); 967 + 968 + void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 969 + struct ieee80211_sta *sta, struct dentry *dir) 970 + { 971 + debugfs_create_file("hw-queues", 0400, dir, sta, &mt7996_queues_fops); 972 + } 973 + 974 + static ssize_t mt7996_link_sta_fixed_rate_set(struct file *file, 975 + const char __user *user_buf, 976 + size_t count, loff_t *ppos) 959 977 { 960 978 #define SHORT_PREAMBLE 0 961 979 #define LONG_PREAMBLE 1 962 - struct ieee80211_sta *sta = file->private_data; 963 - struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; 980 + struct ieee80211_link_sta *link_sta = file->private_data; 981 + struct mt7996_sta *msta = (struct mt7996_sta *)link_sta->sta->drv_priv; 964 982 struct mt7996_dev *dev = msta->vif->deflink.phy->dev; 965 - struct mt7996_sta_link *msta_link = &msta->deflink; 983 + struct mt7996_sta_link *msta_link; 966 984 struct ra_rate phy = {}; 967 985 char buf[100]; 968 986 int ret; ··· 999 981 1000 982 /* mode - cck: 0, ofdm: 1, ht: 2, gf: 3, vht: 4, he_su: 8, he_er: 9 EHT: 15 1001 983 * bw - bw20: 0, bw40: 1, bw80: 2, bw160: 3, BW320: 4 1002 - * nss - vht: 1~4, he: 1~4, eht: 1~4, others: ignore 1003 984 * mcs - cck: 0~4, ofdm: 0~7, ht: 0~32, vht: 0~9, he_su: 0~11, he_er: 0~2, eht: 0~13 985 + * nss - vht: 1~4, he: 1~4, eht: 1~4, others: ignore 1004 986 * gi - (ht/vht) lgi: 0, sgi: 1; (he) 0.8us: 0, 1.6us: 1, 3.2us: 2 1005 987 * preamble - short: 1, long: 0 1006 - * ldpc - off: 0, on: 1 1007 988 * stbc - off: 0, on: 1 989 + * ldpc - off: 0, on: 1 990 + * spe - off: 0, on: 1 1008 991 * ltf - 1xltf: 0, 2xltf: 1, 4xltf: 2 1009 992 */ 1010 993 if (sscanf(buf, "%hhu %hhu %hhu %hhu %hu %hhu %hhu %hhu %hhu %hu", ··· 1013 994 &phy.preamble, &phy.stbc, &phy.ldpc, &phy.spe, &ltf) != 10) { 1014 995 dev_warn(dev->mt76.dev, 1015 996 "format: Mode BW MCS NSS GI Preamble STBC LDPC SPE ltf\n"); 1016 - goto out; 997 + return -EINVAL; 1017 998 } 1018 999 1000 + mutex_lock(&dev->mt76.mutex); 1001 + 1002 + msta_link = mt76_dereference(msta->link[link_sta->link_id], &dev->mt76); 1003 + if (!msta_link) { 1004 + ret = -EINVAL; 1005 + goto out; 1006 + } 1019 1007 phy.wlan_idx = cpu_to_le16(msta_link->wcid.idx); 1020 1008 phy.gi = cpu_to_le16(gi); 1021 1009 phy.ltf = cpu_to_le16(ltf); ··· 1031 1005 1032 1006 ret = mt7996_mcu_set_fixed_rate_ctrl(dev, &phy, 0); 1033 1007 if (ret) 1034 - return -EFAULT; 1008 + goto out; 1035 1009 1010 + ret = count; 1036 1011 out: 1037 - return count; 1012 + mutex_unlock(&dev->mt76.mutex); 1013 + return ret; 1038 1014 } 1039 1015 1040 1016 static const struct file_operations fops_fixed_rate = { 1041 - .write = mt7996_sta_fixed_rate_set, 1017 + .write = mt7996_link_sta_fixed_rate_set, 1042 1018 .open = simple_open, 1043 1019 .owner = THIS_MODULE, 1044 1020 .llseek = default_llseek, 1045 1021 }; 1046 1022 1047 - static int 1048 - mt7996_queues_show(struct seq_file *s, void *data) 1023 + void mt7996_link_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1024 + struct ieee80211_link_sta *link_sta, 1025 + struct dentry *dir) 1049 1026 { 1050 - struct ieee80211_sta *sta = s->private; 1051 - 1052 - mt7996_sta_hw_queue_read(s, sta); 1053 - 1054 - return 0; 1055 - } 1056 - 1057 - DEFINE_SHOW_ATTRIBUTE(mt7996_queues); 1058 - 1059 - void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1060 - struct ieee80211_sta *sta, struct dentry *dir) 1061 - { 1062 - debugfs_create_file("fixed_rate", 0600, dir, sta, &fops_fixed_rate); 1063 - debugfs_create_file("hw-queues", 0400, dir, sta, &mt7996_queues_fops); 1027 + debugfs_create_file("fixed_rate", 0600, dir, link_sta, &fops_fixed_rate); 1064 1028 } 1065 1029 1066 1030 #endif
+23 -10
drivers/net/wireless/mediatek/mt76/mt7996/dma.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 22 22 else 23 23 flags = MT_WED_Q_TX(idx); 24 24 } 25 + 26 + if (mt76_npu_device_active(&dev->mt76)) 27 + flags = MT_NPU_Q_TX(phy->mt76->band_idx); 25 28 26 29 return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc, 27 30 ring_base, wed, flags); ··· 347 344 mtk_wed_device_start(wed, wed_irq_mask); 348 345 } 349 346 350 - if (!mt7996_has_wa(dev)) 347 + if (!mt7996_has_wa(dev) || mt76_npu_device_active(&dev->mt76)) 351 348 irq_mask &= ~(MT_INT_RX(MT_RXQ_MAIN_WA) | 352 349 MT_INT_RX(MT_RXQ_BAND1_WA)); 353 350 irq_mask = reset ? MT_INT_MCU_CMD : irq_mask; ··· 505 502 mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].flags = MT_WED_RRO_Q_RXDMAD_C; 506 503 if (mtk_wed_device_active(&mdev->mmio.wed)) 507 504 mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].wed = &mdev->mmio.wed; 508 - else 505 + else if (!mt76_npu_device_active(&dev->mt76)) 509 506 mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].flags |= MT_QFLAG_EMI_EN; 510 507 ret = mt76_queue_alloc(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C], 511 508 MT_RXQ_ID(MT_RXQ_RRO_RXDMAD_C), ··· 515 512 if (ret) 516 513 return ret; 517 514 518 - /* We need to set cpu idx pointer before resetting the EMI 519 - * queues. 520 - */ 521 - mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].emi_cpu_idx = 522 - &dev->wed_rro.emi_rings_cpu.ptr->ring[0].idx; 523 - mt76_queue_reset(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C], true); 515 + if (!mtk_wed_device_active(&mdev->mmio.wed)) { 516 + /* We need to set cpu idx pointer before resetting the 517 + * EMI queues. 518 + */ 519 + mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].emi_cpu_idx = 520 + &dev->wed_rro.emi_rings_cpu.ptr->ring[0].idx; 521 + mt76_queue_reset(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C], 522 + true); 523 + } 524 524 goto start_hw_rro; 525 525 } 526 526 ··· 616 610 mt76_queue_rx_init(dev, MT_RXQ_MSDU_PAGE_BAND0, 617 611 mt76_dma_rx_poll); 618 612 } 619 - mt7996_irq_enable(dev, MT_INT_RRO_RX_DONE); 613 + 614 + if (!mt76_npu_device_active(&dev->mt76)) 615 + mt7996_irq_enable(dev, MT_INT_RRO_RX_DONE); 620 616 } 621 617 622 618 return 0; ··· 892 884 if (ret < 0) 893 885 return ret; 894 886 887 + ret = mt7996_npu_rx_queues_init(dev); 888 + if (ret) 889 + return ret; 890 + 895 891 netif_napi_add_tx(dev->mt76.tx_napi_dev, &dev->mt76.tx_napi, 896 892 mt7996_poll_tx); 897 893 napi_enable(&dev->mt76.tx_napi); ··· 953 941 if (mtk_wed_device_active(&dev->mt76.mmio.wed)) 954 942 mtk_wed_device_dma_reset(&dev->mt76.mmio.wed); 955 943 944 + mt76_npu_disable_irqs(&dev->mt76); 956 945 mt7996_dma_disable(dev, force); 957 946 mt76_wed_dma_reset(&dev->mt76); 958 947
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/eeprom.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */
+28 -6
drivers/net/wireless/mediatek/mt76/mt7996/init.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 475 475 hw->max_tx_aggregation_subframes = 512; 476 476 477 477 hw->netdev_features = NETIF_F_RXCSUM; 478 - if (mtk_wed_device_active(wed)) 478 + if (mtk_wed_device_active(wed) || mt76_npu_device_active(mdev)) 479 479 hw->netdev_features |= NETIF_F_HW_TC; 480 480 481 481 hw->radiotap_timestamp.units_pos = ··· 830 830 MT_RRO_3_0_EMU_CONF_EN_MASK); 831 831 mt76_set(dev, MT_RRO_3_1_GLOBAL_CONFIG, 832 832 MT_RRO_3_1_GLOBAL_CONFIG_RXDMAD_SEL); 833 - if (!mtk_wed_device_active(&dev->mt76.mmio.wed)) { 833 + if (!mtk_wed_device_active(&dev->mt76.mmio.wed) && 834 + !mt76_npu_device_active(&dev->mt76)) { 834 835 mt76_set(dev, MT_RRO_3_1_GLOBAL_CONFIG, 835 836 MT_RRO_3_1_GLOBAL_CONFIG_RX_DIDX_WR_EN | 836 837 MT_RRO_3_1_GLOBAL_CONFIG_RX_CIDX_RD_EN); ··· 960 959 MT7996_RRO_MSDU_PG_SIZE_PER_CR); 961 960 } 962 961 963 - if (dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) { 962 + if (!mtk_wed_device_active(&dev->mt76.mmio.wed) && 963 + dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) { 964 964 ptr = dmam_alloc_coherent(dev->mt76.dma_dev, 965 - sizeof(dev->wed_rro.emi_rings_cpu.ptr), 965 + sizeof(*dev->wed_rro.emi_rings_cpu.ptr), 966 966 &dev->wed_rro.emi_rings_cpu.phy_addr, 967 967 GFP_KERNEL); 968 968 if (!ptr) ··· 972 970 dev->wed_rro.emi_rings_cpu.ptr = ptr; 973 971 974 972 ptr = dmam_alloc_coherent(dev->mt76.dma_dev, 975 - sizeof(dev->wed_rro.emi_rings_dma.ptr), 973 + sizeof(*dev->wed_rro.emi_rings_dma.ptr), 976 974 &dev->wed_rro.emi_rings_dma.phy_addr, 977 975 GFP_KERNEL); 978 976 if (!ptr) ··· 1038 1036 dev->wed_rro.msdu_pg[i].phy_addr); 1039 1037 } 1040 1038 1039 + if (dev->wed_rro.emi_rings_cpu.ptr) 1040 + dmam_free_coherent(dev->mt76.dma_dev, 1041 + sizeof(*dev->wed_rro.emi_rings_cpu.ptr), 1042 + dev->wed_rro.emi_rings_cpu.ptr, 1043 + dev->wed_rro.emi_rings_cpu.phy_addr); 1044 + 1045 + if (dev->wed_rro.emi_rings_dma.ptr) 1046 + dmam_free_coherent(dev->mt76.dma_dev, 1047 + sizeof(*dev->wed_rro.emi_rings_dma.ptr), 1048 + dev->wed_rro.emi_rings_dma.ptr, 1049 + dev->wed_rro.emi_rings_dma.phy_addr); 1050 + 1041 1051 if (!dev->wed_rro.session.ptr) 1042 1052 return; 1043 1053 ··· 1081 1067 list); 1082 1068 list_del_init(&e->list); 1083 1069 1070 + if (mt76_npu_device_active(&dev->mt76)) 1071 + goto reset_session; 1072 + 1084 1073 for (i = 0; i < MT7996_RRO_WINDOW_MAX_LEN; i++) { 1085 1074 void *ptr = dev->wed_rro.session.ptr; 1086 1075 struct mt7996_wed_rro_addr *elem; ··· 1104 1087 elem = ptr + elem_id * sizeof(*elem); 1105 1088 elem->data |= cpu_to_le32(val); 1106 1089 } 1090 + reset_session: 1107 1091 mt7996_mcu_wed_rro_reset_sessions(dev, e->id); 1108 1092 out: 1109 1093 kfree(e); ··· 1689 1671 return ret; 1690 1672 1691 1673 ret = mt7996_register_phy(dev, MT_BAND2); 1674 + if (ret) 1675 + return ret; 1676 + 1677 + ret = mt7996_npu_hw_init(dev); 1692 1678 if (ret) 1693 1679 return ret; 1694 1680
+51 -11
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 718 718 status->flag |= RX_FLAG_8023; 719 719 mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb, 720 720 *info); 721 + mt76_npu_check_ppe(&dev->mt76, skb, *info); 721 722 } 722 723 723 724 if (rxv && !(status->flag & RX_FLAG_8023)) { ··· 795 794 u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; 796 795 __le16 fc = hdr->frame_control, sc = hdr->seq_ctrl; 797 796 u16 seqno = le16_to_cpu(sc); 797 + bool hw_bigtk = false; 798 798 u8 fc_type, fc_stype; 799 799 u32 val; 800 800 ··· 821 819 info->flags & IEEE80211_TX_CTL_USE_MINRATE) 822 820 val |= MT_TXD1_FIXED_RATE; 823 821 824 - if (key && multicast && ieee80211_is_robust_mgmt_frame(skb)) { 822 + if (is_mt7990(&dev->mt76) && ieee80211_is_beacon(fc) && 823 + (wcid->hw_key_idx2 == 6 || wcid->hw_key_idx2 == 7)) 824 + hw_bigtk = true; 825 + 826 + if ((key && multicast && ieee80211_is_robust_mgmt_frame(skb)) || hw_bigtk) { 825 827 val |= MT_TXD1_BIP; 826 828 txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); 827 829 } ··· 1040 1034 struct ieee80211_sta *sta, 1041 1035 struct mt76_tx_info *tx_info) 1042 1036 { 1037 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data; 1043 1038 struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); 1044 1039 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); 1045 1040 struct ieee80211_key_conf *key = info->control.hw_key; 1046 1041 struct ieee80211_vif *vif = info->control.vif; 1042 + struct mt7996_vif *mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL; 1043 + struct mt7996_sta *msta = sta ? (struct mt7996_sta *)sta->drv_priv : NULL; 1044 + struct mt76_vif_link *mlink = NULL; 1047 1045 struct mt76_txwi_cache *t; 1048 1046 int id, i, pid, nbuf = tx_info->nbuf - 1; 1049 1047 bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; 1050 1048 __le32 *ptr = (__le32 *)txwi_ptr; 1051 1049 u8 *txwi = (u8 *)txwi_ptr; 1050 + u8 link_id; 1052 1051 1053 1052 if (unlikely(tx_info->skb->len <= ETH_HLEN)) 1054 1053 return -EINVAL; 1055 1054 1056 1055 if (!wcid) 1057 1056 wcid = &dev->mt76.global_wcid; 1057 + 1058 + if ((is_8023 || ieee80211_is_data_qos(hdr->frame_control)) && sta->mlo && 1059 + likely(tx_info->skb->protocol != cpu_to_be16(ETH_P_PAE))) { 1060 + u8 tid = tx_info->skb->priority & IEEE80211_QOS_CTL_TID_MASK; 1061 + 1062 + link_id = (tid % 2) ? msta->seclink_id : msta->deflink_id; 1063 + } else { 1064 + link_id = u32_get_bits(info->control.flags, 1065 + IEEE80211_TX_CTRL_MLO_LINK); 1066 + } 1067 + 1068 + if (link_id != wcid->link_id && link_id != IEEE80211_LINK_UNSPECIFIED) { 1069 + if (msta) { 1070 + struct mt7996_sta_link *msta_link = 1071 + rcu_dereference(msta->link[link_id]); 1072 + 1073 + if (msta_link) 1074 + wcid = &msta_link->wcid; 1075 + } else if (mvif) { 1076 + mlink = rcu_dereference(mvif->mt76.link[link_id]); 1077 + if (mlink && mlink->wcid) 1078 + wcid = mlink->wcid; 1079 + } 1080 + } 1058 1081 1059 1082 t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size); 1060 1083 t->skb = tx_info->skb; ··· 1189 1154 if (!is_8023 && mt7996_tx_use_mgmt(dev, tx_info->skb)) 1190 1155 txp->fw.flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME); 1191 1156 1192 - if (vif) { 1193 - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; 1194 - struct mt76_vif_link *mlink = NULL; 1195 - 1157 + if (mvif) { 1196 1158 if (wcid->offchannel) 1197 1159 mlink = rcu_dereference(mvif->mt76.offchannel_link); 1198 1160 if (!mlink) ··· 1713 1681 if (!list_empty(&dev->wed_rro.page_cache)) { 1714 1682 p = list_first_entry(&dev->wed_rro.page_cache, 1715 1683 struct mt7996_msdu_page, list); 1716 - if (p) 1717 - list_del(&p->list); 1684 + list_del(&p->list); 1718 1685 } 1719 1686 1720 1687 spin_unlock(&dev->wed_rro.lock); ··· 2368 2337 if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) 2369 2338 continue; 2370 2339 2371 - ret = mt7996_run(&dev->phy); 2340 + ret = mt7996_run(phy); 2372 2341 if (ret) 2373 2342 goto out; 2374 2343 } ··· 2450 2419 cancel_work_sync(&dev->wed_rro.work); 2451 2420 mt7996_for_each_phy(dev, phy) 2452 2421 cancel_delayed_work_sync(&phy->mt76->mac_work); 2422 + 2423 + mt76_abort_scan(&dev->mt76); 2453 2424 2454 2425 mutex_lock(&dev->mt76.mutex); 2455 2426 for (i = 0; i < 10; i++) { ··· 2569 2536 2570 2537 mutex_lock(&dev->mt76.mutex); 2571 2538 2539 + mt7996_npu_hw_stop(dev); 2540 + 2572 2541 mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED); 2573 2542 2574 2543 if (mt7996_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) { ··· 2586 2551 mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE); 2587 2552 mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE); 2588 2553 2589 - /* enable DMA Tx/Tx and interrupt */ 2554 + /* enable DMA Rx/Tx and interrupt */ 2590 2555 mt7996_dma_start(dev, false, false); 2591 2556 2592 2557 if (!is_mt7996(&dev->mt76) && dev->mt76.hwrro_mode == MT76_HWRRO_V3) ··· 2634 2599 local_bh_enable(); 2635 2600 2636 2601 ieee80211_wake_queues(hw); 2602 + mt7996_update_beacons(dev); 2637 2603 2638 2604 mutex_unlock(&dev->mt76.mutex); 2639 2605 2640 - mt7996_update_beacons(dev); 2606 + mt7996_npu_hw_init(dev); 2641 2607 2642 2608 mt7996_for_each_phy(dev, phy) 2643 2609 ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, ··· 2890 2854 LIST_HEAD(list); 2891 2855 u32 changed; 2892 2856 2857 + mutex_lock(&dev->mt76.mutex); 2858 + 2893 2859 spin_lock_bh(&dev->mt76.sta_poll_lock); 2894 2860 list_splice_init(&dev->sta_rc_list, &list); 2895 2861 ··· 2924 2886 } 2925 2887 2926 2888 spin_unlock_bh(&dev->mt76.sta_poll_lock); 2889 + 2890 + mutex_unlock(&dev->mt76.mutex); 2927 2891 } 2928 2892 2929 2893 void mt7996_mac_work(struct work_struct *work)
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/mac.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */
+99 -54
drivers/net/wireless/mediatek/mt76/mt7996/main.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 90 90 { 91 91 } 92 92 93 - static inline int get_free_idx(u32 mask, u8 start, u8 end) 93 + static inline int get_free_idx(u64 mask, u8 start, u8 end) 94 94 { 95 - return ffs(~mask & GENMASK(end, start)); 95 + if (~mask & GENMASK_ULL(end, start)) 96 + return __ffs64(~mask & GENMASK_ULL(end, start)) + 1; 97 + return 0; 96 98 } 97 99 98 100 static int get_omac_idx(enum nl80211_iftype type, u64 mask) ··· 249 247 else if (idx == *wcid_keyidx) 250 248 *wcid_keyidx = -1; 251 249 252 - if (cmd != SET_KEY && sta) 250 + /* only do remove key for BIGTK */ 251 + if (cmd != SET_KEY && !is_bigtk) 253 252 return 0; 254 253 255 254 mt76_wcid_key_setup(&dev->mt76, &msta_link->wcid, key); 256 255 257 - err = mt7996_mcu_add_key(&dev->mt76, vif, key, 256 + err = mt7996_mcu_add_key(&dev->mt76, link, key, 258 257 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), 259 258 &msta_link->wcid, cmd); 260 259 ··· 311 308 if (idx < 0) 312 309 return -ENOSPC; 313 310 314 - if (!dev->mld_idx_mask) { /* first link in the group */ 315 - mvif->mld_group_idx = get_own_mld_idx(dev->mld_idx_mask, true); 316 - mvif->mld_remap_idx = get_free_idx(dev->mld_remap_idx_mask, 317 - 0, 15); 318 - } 319 - 320 311 mld_idx = get_own_mld_idx(dev->mld_idx_mask, false); 321 312 if (mld_idx < 0) 322 313 return -ENOSPC; ··· 328 331 return ret; 329 332 330 333 dev->mt76.vif_mask |= BIT_ULL(mlink->idx); 331 - if (!dev->mld_idx_mask) { 332 - dev->mld_idx_mask |= BIT_ULL(mvif->mld_group_idx); 333 - dev->mld_remap_idx_mask |= BIT_ULL(mvif->mld_remap_idx); 334 - } 335 334 dev->mld_idx_mask |= BIT_ULL(link->mld_idx); 336 335 phy->omac_mask |= BIT_ULL(mlink->omac_idx); 337 336 ··· 336 343 INIT_LIST_HEAD(&msta_link->rc_list); 337 344 msta_link->wcid.idx = idx; 338 345 msta_link->wcid.link_id = link_conf->link_id; 346 + msta_link->wcid.link_valid = ieee80211_vif_is_mld(vif); 339 347 msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; 340 348 mt76_wcid_init(&msta_link->wcid, band_idx); 341 349 ··· 370 376 371 377 ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, &it); 372 378 373 - if (mvif->mt76.deflink_id == IEEE80211_LINK_UNSPECIFIED) 379 + if (!mlink->wcid->offchannel && 380 + mvif->mt76.deflink_id == IEEE80211_LINK_UNSPECIFIED) 374 381 mvif->mt76.deflink_id = link_conf->link_id; 375 382 376 383 return 0; ··· 392 397 }; 393 398 int idx = msta_link->wcid.idx; 394 399 395 - ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, &it); 400 + if (!mlink->wcid->offchannel) 401 + ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, &it); 396 402 397 403 mt7996_mcu_add_sta(dev, link_conf, NULL, link, NULL, 398 404 CONN_STATE_DISCONNECT, false); ··· 403 407 404 408 rcu_assign_pointer(dev->mt76.wcid[idx], NULL); 405 409 406 - if (mvif->mt76.deflink_id == link_conf->link_id) { 410 + if (!mlink->wcid->offchannel && 411 + mvif->mt76.deflink_id == link_conf->link_id) { 407 412 struct ieee80211_bss_conf *iter; 408 413 unsigned int link_id; 409 414 ··· 420 423 dev->mt76.vif_mask &= ~BIT_ULL(mlink->idx); 421 424 dev->mld_idx_mask &= ~BIT_ULL(link->mld_idx); 422 425 phy->omac_mask &= ~BIT_ULL(mlink->omac_idx); 423 - if (!(dev->mld_idx_mask & ~BIT_ULL(mvif->mld_group_idx))) { 424 - /* last link */ 425 - dev->mld_idx_mask &= ~BIT_ULL(mvif->mld_group_idx); 426 - dev->mld_remap_idx_mask &= ~BIT_ULL(mvif->mld_remap_idx); 427 - } 428 426 429 427 spin_lock_bh(&dev->mt76.sta_poll_lock); 430 428 if (!list_empty(&msta_link->wcid.poll_list)) ··· 657 665 unsigned int link_id, u16 queue, 658 666 const struct ieee80211_tx_queue_params *params) 659 667 { 660 - struct mt7996_dev *dev = mt7996_hw_dev(hw); 661 - struct mt7996_vif_link *mlink = mt7996_vif_link(dev, vif, link_id); 668 + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; 669 + struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; 662 670 static const u8 mq_to_aci[] = { 663 671 [IEEE80211_AC_VO] = 3, 664 672 [IEEE80211_AC_VI] = 2, ··· 667 675 }; 668 676 669 677 /* firmware uses access class index */ 670 - mlink->queue_params[mq_to_aci[queue]] = *params; 678 + link_info->queue_params[mq_to_aci[queue]] = *params; 671 679 /* no need to update right away, we'll get BSS_CHANGED_QOS */ 672 680 673 681 return 0; ··· 954 962 955 963 msta_link = &msta->deflink; 956 964 msta->deflink_id = link_id; 965 + msta->seclink_id = msta->deflink_id; 957 966 958 967 for (i = 0; i < ARRAY_SIZE(sta->txq); i++) { 959 968 struct mt76_txq *mtxq; ··· 969 976 msta_link = kzalloc(sizeof(*msta_link), GFP_KERNEL); 970 977 if (!msta_link) 971 978 return -ENOMEM; 979 + 980 + if (msta->seclink_id == msta->deflink_id && 981 + (sta->valid_links & ~BIT(msta->deflink_id))) 982 + msta->seclink_id = __ffs(sta->valid_links & 983 + ~BIT(msta->deflink_id)); 972 984 } 973 985 974 986 INIT_LIST_HEAD(&msta_link->rc_list); ··· 982 984 msta_link->wcid.sta = 1; 983 985 msta_link->wcid.idx = idx; 984 986 msta_link->wcid.link_id = link_id; 987 + msta_link->wcid.link_valid = !!sta->valid_links; 985 988 msta_link->wcid.def_wcid = &msta->deflink.wcid; 986 989 987 990 ewma_avg_signal_init(&msta_link->avg_ack_signal); ··· 1048 1049 if (msta->deflink_id == link_id) { 1049 1050 msta->deflink_id = IEEE80211_LINK_UNSPECIFIED; 1050 1051 continue; 1052 + } else if (msta->seclink_id == link_id) { 1053 + msta->seclink_id = IEEE80211_LINK_UNSPECIFIED; 1051 1054 } 1052 1055 1053 1056 kfree_rcu(msta_link, rcu_head); ··· 1145 1144 mutex_lock(&dev->mt76.mutex); 1146 1145 1147 1146 msta->deflink_id = IEEE80211_LINK_UNSPECIFIED; 1147 + msta->seclink_id = IEEE80211_LINK_UNSPECIFIED; 1148 1148 msta->vif = mvif; 1149 1149 err = mt7996_mac_sta_add_links(dev, vif, sta, links); 1150 1150 ··· 1162 1160 unsigned long links = sta->valid_links; 1163 1161 struct ieee80211_link_sta *link_sta; 1164 1162 unsigned int link_id; 1163 + int err = 0; 1164 + 1165 + mutex_lock(&dev->mt76.mutex); 1165 1166 1166 1167 for_each_sta_active_link(vif, sta, link_sta, link_id) { 1167 1168 struct ieee80211_bss_conf *link_conf; 1168 1169 struct mt7996_sta_link *msta_link; 1169 1170 struct mt7996_vif_link *link; 1170 - int i, err; 1171 + int i; 1171 1172 1172 1173 link_conf = link_conf_dereference_protected(vif, link_id); 1173 1174 if (!link_conf) ··· 1190 1185 link, msta_link, 1191 1186 CONN_STATE_CONNECT, true); 1192 1187 if (err) 1193 - return err; 1188 + goto unlock; 1194 1189 1195 1190 err = mt7996_mcu_add_rate_ctrl(dev, msta_link->sta, vif, 1196 1191 link_id, false); 1197 1192 if (err) 1198 - return err; 1193 + goto unlock; 1199 1194 1200 1195 msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; 1201 1196 break; ··· 1204 1199 link, msta_link, 1205 1200 CONN_STATE_PORT_SECURE, false); 1206 1201 if (err) 1207 - return err; 1202 + goto unlock; 1208 1203 break; 1209 1204 case MT76_STA_EVENT_DISASSOC: 1210 1205 for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) 1211 1206 mt7996_mac_twt_teardown_flow(dev, link, 1212 1207 msta_link, i); 1213 1208 1214 - if (sta->mlo && links == BIT(link_id)) /* last link */ 1215 - mt7996_mcu_teardown_mld_sta(dev, link, 1216 - msta_link); 1217 - else 1209 + if (!sta->mlo) 1218 1210 mt7996_mcu_add_sta(dev, link_conf, link_sta, 1219 1211 link, msta_link, 1220 1212 CONN_STATE_DISCONNECT, false); 1213 + else if (sta->mlo && links == BIT(link_id)) /* last link */ 1214 + mt7996_mcu_teardown_mld_sta(dev, link, 1215 + msta_link); 1221 1216 msta_link->wcid.sta_disabled = 1; 1222 1217 msta_link->wcid.sta = 0; 1223 1218 links = links & ~BIT(link_id); 1224 1219 break; 1225 1220 } 1226 1221 } 1222 + unlock: 1223 + mutex_unlock(&dev->mt76.mutex); 1227 1224 1228 - return 0; 1225 + return err; 1229 1226 } 1230 1227 1231 1228 static void ··· 1346 1339 } 1347 1340 1348 1341 if (mvif) { 1349 - struct mt76_vif_link *mlink = &mvif->deflink.mt76; 1342 + struct mt76_vif_link *mlink; 1350 1343 1351 - if (link_id < IEEE80211_LINK_UNSPECIFIED) 1352 - mlink = rcu_dereference(mvif->mt76.link[link_id]); 1353 - 1354 - if (mlink->wcid) 1344 + mlink = rcu_dereference(mvif->mt76.link[link_id]); 1345 + if (mlink && mlink->wcid) 1355 1346 wcid = mlink->wcid; 1356 1347 1357 1348 if (mvif->mt76.roc_phy && ··· 1357 1352 mphy = mvif->mt76.roc_phy; 1358 1353 if (mphy->roc_link) 1359 1354 wcid = mphy->roc_link->wcid; 1360 - } else { 1355 + } else if (mlink) { 1361 1356 mphy = mt76_vif_link_phy(mlink); 1362 1357 } 1363 1358 } ··· 1367 1362 goto unlock; 1368 1363 } 1369 1364 1370 - if (msta && link_id < IEEE80211_LINK_UNSPECIFIED) { 1365 + if (msta) { 1371 1366 struct mt7996_sta_link *msta_link; 1372 1367 1373 1368 msta_link = rcu_dereference(msta->link[link_id]); ··· 2164 2159 return ret; 2165 2160 } 2166 2161 2167 - #ifdef CONFIG_NET_MEDIATEK_SOC_WED 2168 2162 static int 2169 2163 mt7996_net_fill_forward_path(struct ieee80211_hw *hw, 2170 2164 struct ieee80211_vif *vif, ··· 2171 2167 struct net_device_path_ctx *ctx, 2172 2168 struct net_device_path *path) 2173 2169 { 2174 - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; 2175 2170 struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; 2176 2171 struct mt7996_dev *dev = mt7996_hw_dev(hw); 2177 2172 struct mtk_wed_device *wed = &dev->mt76.mmio.wed; 2178 2173 struct mt7996_sta_link *msta_link; 2179 - struct mt76_vif_link *mlink; 2174 + struct mt7996_vif_link *link; 2180 2175 2181 - mlink = rcu_dereference(mvif->mt76.link[msta->deflink_id]); 2182 - if (!mlink) 2176 + link = mt7996_vif_link(dev, vif, msta->deflink_id); 2177 + if (!link) 2183 2178 return -EIO; 2184 2179 2185 2180 msta_link = rcu_dereference(msta->link[msta->deflink_id]); ··· 2193 2190 (is_mt7992(&dev->mt76) && msta_link->wcid.phy_idx == MT_BAND1))) 2194 2191 wed = &dev->mt76.mmio.wed_hif2; 2195 2192 2196 - if (!mtk_wed_device_active(wed)) 2193 + if (!mtk_wed_device_active(wed) && 2194 + !mt76_npu_device_active(&dev->mt76)) 2197 2195 return -ENODEV; 2198 2196 2199 2197 path->type = DEV_PATH_MTK_WDMA; 2200 2198 path->dev = ctx->dev; 2201 - path->mtk_wdma.wdma_idx = wed->wdma_idx; 2202 - path->mtk_wdma.bss = mlink->idx; 2199 + #ifdef CONFIG_NET_MEDIATEK_SOC_WED 2200 + if (mtk_wed_device_active(wed)) 2201 + path->mtk_wdma.wdma_idx = wed->wdma_idx; 2202 + else 2203 + #endif 2204 + path->mtk_wdma.wdma_idx = link->mt76.band_idx; 2205 + path->mtk_wdma.bss = link->mt76.idx; 2203 2206 path->mtk_wdma.queue = 0; 2204 2207 path->mtk_wdma.wcid = msta_link->wcid.idx; 2205 2208 ··· 2219 2210 return 0; 2220 2211 } 2221 2212 2222 - #endif 2223 - 2224 2213 static int 2225 2214 mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2226 2215 u16 old_links, u16 new_links, 2227 2216 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 2228 2217 { 2229 - return 0; 2218 + struct mt7996_dev *dev = mt7996_hw_dev(hw); 2219 + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; 2220 + int ret = 0; 2221 + 2222 + mutex_lock(&dev->mt76.mutex); 2223 + 2224 + if (!old_links) { 2225 + int idx; 2226 + 2227 + idx = get_own_mld_idx(dev->mld_idx_mask, true); 2228 + if (idx < 0) { 2229 + ret = -ENOSPC; 2230 + goto out; 2231 + } 2232 + mvif->mld_group_idx = idx; 2233 + dev->mld_idx_mask |= BIT_ULL(mvif->mld_group_idx); 2234 + 2235 + idx = get_free_idx(dev->mld_remap_idx_mask, 0, 15) - 1; 2236 + if (idx < 0) { 2237 + ret = -ENOSPC; 2238 + goto out; 2239 + } 2240 + mvif->mld_remap_idx = idx; 2241 + dev->mld_remap_idx_mask |= BIT_ULL(mvif->mld_remap_idx); 2242 + } 2243 + 2244 + if (new_links) 2245 + goto out; 2246 + 2247 + dev->mld_idx_mask &= ~BIT_ULL(mvif->mld_group_idx); 2248 + dev->mld_remap_idx_mask &= ~BIT_ULL(mvif->mld_remap_idx); 2249 + 2250 + out: 2251 + mutex_unlock(&dev->mt76.mutex); 2252 + 2253 + return ret; 2230 2254 } 2231 2255 2232 2256 static void ··· 2325 2283 .twt_teardown_request = mt7996_twt_teardown_request, 2326 2284 #ifdef CONFIG_MAC80211_DEBUGFS 2327 2285 .sta_add_debugfs = mt7996_sta_add_debugfs, 2286 + .link_sta_add_debugfs = mt7996_link_sta_add_debugfs, 2328 2287 #endif 2329 2288 .set_radar_background = mt7996_set_radar_background, 2330 - #ifdef CONFIG_NET_MEDIATEK_SOC_WED 2331 2289 .net_fill_forward_path = mt7996_net_fill_forward_path, 2290 + #ifdef CONFIG_NET_MEDIATEK_SOC_WED 2332 2291 .net_setup_tc = mt76_wed_net_setup_tc, 2292 + #elif defined(CONFIG_MT7996_NPU) 2293 + .net_setup_tc = mt76_npu_net_setup_tc, 2333 2294 #endif 2334 2295 .change_vif_links = mt7996_change_vif_links, 2335 2296 .change_sta_links = mt7996_mac_sta_change_links,
+49 -29
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 317 317 uni_txd->option = MCU_CMD_UNI_QUERY_ACK; 318 318 else 319 319 uni_txd->option = MCU_CMD_UNI_EXT_ACK; 320 + 321 + if (mcu_cmd == MCU_UNI_CMD_SDO) 322 + uni_txd->option &= ~MCU_CMD_ACK; 320 323 321 324 if ((cmd & __MCU_CMD_FIELD_WA) && (cmd & __MCU_CMD_FIELD_WM)) 322 325 uni_txd->s2d_index = MCU_S2D_H2CN; ··· 1037 1034 struct mt76_connac_bss_basic_tlv *bss; 1038 1035 u32 type = CONNECTION_INFRA_AP; 1039 1036 u16 sta_wlan_idx = wlan_idx; 1040 - struct ieee80211_sta *sta; 1041 1037 struct tlv *tlv; 1042 1038 int idx; 1043 1039 ··· 1047 1045 break; 1048 1046 case NL80211_IFTYPE_STATION: 1049 1047 if (enable) { 1050 - rcu_read_lock(); 1051 - sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); 1052 - /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ 1053 - if (sta) { 1054 - struct mt76_wcid *wcid; 1048 + struct ieee80211_sta *sta; 1055 1049 1056 - wcid = (struct mt76_wcid *)sta->drv_priv; 1057 - sta_wlan_idx = wcid->idx; 1050 + rcu_read_lock(); 1051 + sta = ieee80211_find_sta(vif, link_conf->bssid); 1052 + if (sta) { 1053 + struct mt7996_sta *msta = (void *)sta->drv_priv; 1054 + struct mt7996_sta_link *msta_link; 1055 + int link_id = link_conf->link_id; 1056 + 1057 + msta_link = rcu_dereference(msta->link[link_id]); 1058 + if (msta_link) 1059 + sta_wlan_idx = msta_link->wcid.idx; 1058 1060 } 1059 1061 rcu_read_unlock(); 1060 1062 } ··· 1075 1069 tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_BASIC, sizeof(*bss)); 1076 1070 1077 1071 bss = (struct mt76_connac_bss_basic_tlv *)tlv; 1078 - bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); 1079 - bss->dtim_period = link_conf->dtim_period; 1080 1072 bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); 1081 1073 bss->sta_idx = cpu_to_le16(sta_wlan_idx); 1082 1074 bss->conn_type = cpu_to_le32(type); ··· 1094 1090 1095 1091 memcpy(bss->bssid, link_conf->bssid, ETH_ALEN); 1096 1092 bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); 1097 - bss->dtim_period = vif->bss_conf.dtim_period; 1093 + bss->dtim_period = link_conf->dtim_period; 1098 1094 bss->phymode = mt76_connac_get_phy_mode(phy, vif, 1099 1095 chandef->chan->band, NULL); 1100 - bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, &vif->bss_conf, 1096 + bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, link_conf, 1101 1097 chandef->chan->band); 1102 1098 1103 1099 return 0; ··· 1826 1822 bf->ibf_nrow = tx_ant; 1827 1823 1828 1824 if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he) 1829 - bf->ibf_timeout = is_mt7996(&dev->mt76) ? MT7996_IBF_TIMEOUT : 1830 - MT7992_IBF_TIMEOUT; 1825 + bf->ibf_timeout = is_mt7992(&dev->mt76) ? MT7992_IBF_TIMEOUT : 1826 + MT7996_IBF_TIMEOUT; 1831 1827 else if (!ebf && link_sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) 1832 1828 bf->ibf_timeout = MT7996_IBF_TIMEOUT_LEGACY; 1833 1829 else ··· 2394 2390 mld_setup->primary_id = cpu_to_le16(msta_link->wcid.idx); 2395 2391 2396 2392 if (nlinks > 1) { 2397 - link_id = __ffs(sta->valid_links & ~BIT(msta->deflink_id)); 2398 - msta_link = mt76_dereference(msta->link[link_id], &dev->mt76); 2393 + msta_link = mt76_dereference(msta->link[msta->seclink_id], 2394 + &dev->mt76); 2399 2395 if (!msta_link) 2400 2396 return; 2401 2397 } ··· 2530 2526 } 2531 2527 2532 2528 static int 2533 - mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, 2529 + mt7996_mcu_sta_key_tlv(struct mt76_dev *dev, struct mt76_wcid *wcid, 2534 2530 struct sk_buff *skb, 2535 2531 struct ieee80211_key_conf *key, 2536 2532 enum set_key_cmd cmd) ··· 2542 2538 2543 2539 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec)); 2544 2540 sec = (struct sta_rec_sec_uni *)tlv; 2545 - sec->add = 0; 2541 + /* due to connac3 FW design, we only do remove key for BIGTK; even for 2542 + * removal, the field should be filled with SET_KEY 2543 + */ 2544 + sec->add = SET_KEY; 2546 2545 sec->n_cipher = 1; 2547 2546 sec_key = &sec->key[0]; 2548 2547 sec_key->wlan_idx = cpu_to_le16(wcid->idx); ··· 2585 2578 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 2586 2579 sec_key->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256; 2587 2580 break; 2581 + case WLAN_CIPHER_SUITE_BIP_CMAC_256: 2582 + if (!is_mt7990(dev)) 2583 + return -EOPNOTSUPP; 2584 + sec_key->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_256; 2585 + break; 2588 2586 default: 2589 2587 return -EOPNOTSUPP; 2590 2588 } 2591 2589 2592 - sec_key->bcn_mode = BP_SW_MODE; 2590 + sec_key->bcn_mode = is_mt7990(dev) ? BP_HW_MODE : BP_SW_MODE; 2593 2591 2594 2592 return 0; 2595 2593 } 2596 2594 2597 - int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, 2595 + int mt7996_mcu_add_key(struct mt76_dev *dev, struct mt7996_vif_link *link, 2598 2596 struct ieee80211_key_conf *key, int mcu_cmd, 2599 2597 struct mt76_wcid *wcid, enum set_key_cmd cmd) 2600 2598 { 2601 - struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; 2602 2599 struct sk_buff *skb; 2603 2600 int ret; 2604 2601 2605 - skb = __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid, 2606 - MT7996_STA_UPDATE_MAX_SIZE); 2602 + skb = __mt76_connac_mcu_alloc_sta_req(dev, (struct mt76_vif_link *)link, 2603 + wcid, MT7996_STA_UPDATE_MAX_SIZE); 2607 2604 if (IS_ERR(skb)) 2608 2605 return PTR_ERR(skb); 2609 2606 2610 - ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd); 2607 + ret = mt7996_mcu_sta_key_tlv(dev, wcid, skb, key, cmd); 2611 2608 if (ret) { 2612 2609 dev_kfree_skb(skb); 2613 2610 return ret; ··· 2731 2720 static void 2732 2721 mt7996_mcu_beacon_cont(struct mt7996_dev *dev, 2733 2722 struct ieee80211_bss_conf *link_conf, 2723 + struct mt7996_vif_link *link, 2734 2724 struct sk_buff *rskb, struct sk_buff *skb, 2735 2725 struct bss_bcn_content_tlv *bcn, 2736 2726 struct ieee80211_mutable_offsets *offs) 2737 2727 { 2738 - struct mt76_wcid *wcid = &dev->mt76.global_wcid; 2739 - u8 *buf; 2728 + u8 *buf, keyidx = link->msta_link.wcid.hw_key_idx2; 2729 + struct mt76_wcid *wcid; 2730 + 2731 + if (is_mt7990(&dev->mt76) && (keyidx == 6 || keyidx == 7)) 2732 + wcid = &link->msta_link.wcid; 2733 + else 2734 + wcid = &dev->mt76.global_wcid; 2740 2735 2741 2736 bcn->pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len); 2742 2737 bcn->tim_ie_pos = cpu_to_le16(offs->tim_offset); ··· 2817 2800 info = IEEE80211_SKB_CB(skb); 2818 2801 info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, mlink->band_idx); 2819 2802 2820 - mt7996_mcu_beacon_cont(dev, link_conf, rskb, skb, bcn, &offs); 2803 + mt7996_mcu_beacon_cont(dev, link_conf, link, rskb, skb, bcn, &offs); 2821 2804 if (link_conf->bssid_indicator) 2822 2805 mt7996_mcu_beacon_mbss(rskb, skb, bcn, &offs); 2823 2806 mt7996_mcu_beacon_cntdwn(rskb, skb, &offs, link_conf->csa_active); ··· 3431 3414 #define WMM_PARAM_SET (WMM_AIFS_SET | WMM_CW_MIN_SET | \ 3432 3415 WMM_CW_MAX_SET | WMM_TXOP_SET) 3433 3416 struct mt7996_vif_link *link = mt7996_vif_conf_link(dev, vif, link_conf); 3417 + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; 3418 + unsigned int link_id = link_conf->link_id; 3419 + struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; 3434 3420 struct { 3435 3421 u8 bss_idx; 3436 3422 u8 __rsv[3]; ··· 3451 3431 skb_put_data(skb, &hdr, sizeof(hdr)); 3452 3432 3453 3433 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 3454 - struct ieee80211_tx_queue_params *q = &link->queue_params[ac]; 3434 + struct ieee80211_tx_queue_params *q = &link_info->queue_params[ac]; 3455 3435 struct edca *e; 3456 3436 struct tlv *tlv; 3457 3437
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */
+13 -3
drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 595 595 596 596 wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE; 597 597 wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf; 598 + wed->wlan.hif2 = hif2; 598 599 599 600 wed->wlan.amsdu_max_subframes = 8; 600 601 wed->wlan.amsdu_max_len = 1536; ··· 707 706 static void mt7996_rx_poll_complete(struct mt76_dev *mdev, 708 707 enum mt76_rxq_id q) 709 708 { 710 - struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); 709 + if (q == MT_RXQ_NPU0 || q == MT_RXQ_NPU1) { 710 + struct airoha_npu *npu; 711 711 712 - mt7996_irq_enable(dev, MT_INT_RX(q)); 712 + npu = rcu_dereference(mdev->mmio.npu); 713 + if (npu) 714 + airoha_npu_wlan_enable_irq(npu, q - MT_RXQ_NPU0); 715 + } else { 716 + struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, 717 + mt76); 718 + 719 + mt7996_irq_enable(dev, MT_INT_RX(q)); 720 + } 713 721 } 714 722 715 723 /* TODO: support 2/4/6/8 MSI-X vectors */
+34 -4
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 243 243 struct mt7996_sta_link deflink; /* must be first */ 244 244 struct mt7996_sta_link __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; 245 245 u8 deflink_id; 246 + u8 seclink_id; 246 247 247 248 struct mt7996_vif *vif; 248 249 }; ··· 254 253 struct mt7996_sta_link msta_link; 255 254 struct mt7996_phy *phy; 256 255 257 - struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; 258 256 struct cfg80211_bitrate_mask bitrate_mask; 259 257 260 258 u8 mld_idx; 261 259 }; 262 260 261 + struct mt7996_vif_link_info { 262 + struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; 263 + }; 264 + 263 265 struct mt7996_vif { 264 266 struct mt7996_vif_link deflink; /* must be first */ 265 267 struct mt76_vif_data mt76; 268 + 269 + struct mt7996_vif_link_info link_info[IEEE80211_MLD_MAX_NUM_LINKS]; 266 270 267 271 u8 mld_group_idx; 268 272 u8 mld_remap_idx; ··· 787 781 788 782 static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy) 789 783 { 790 - int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx); 784 + int max_nss = hweight16(phy->orig_antenna_mask); 791 785 int cur_nss = hweight8(phy->mt76->antenna_mask); 792 786 u16 tx_chainmask = phy->mt76->chainmask; 793 787 ··· 849 843 int mt7996_init_debugfs(struct mt7996_dev *dev); 850 844 void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len); 851 845 bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len); 852 - int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, 846 + int mt7996_mcu_add_key(struct mt76_dev *dev, struct mt7996_vif_link *link, 853 847 struct ieee80211_key_conf *key, int mcu_cmd, 854 848 struct mt76_wcid *wcid, enum set_key_cmd cmd); 855 849 int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, ··· 864 858 #ifdef CONFIG_MAC80211_DEBUGFS 865 859 void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 866 860 struct ieee80211_sta *sta, struct dentry *dir); 861 + void mt7996_link_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 862 + struct ieee80211_link_sta *link_sta, 863 + struct dentry *dir); 867 864 #endif 868 865 int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr, 869 866 bool hif2, int *irq); ··· 877 868 #endif 878 869 879 870 int mt7996_dma_rro_init(struct mt7996_dev *dev); 871 + 872 + #ifdef CONFIG_MT7996_NPU 873 + int mt7996_npu_hw_init(struct mt7996_dev *dev); 874 + int mt7996_npu_hw_stop(struct mt7996_dev *dev); 875 + int mt7996_npu_rx_queues_init(struct mt7996_dev *dev); 876 + #else 877 + static inline int mt7996_npu_hw_init(struct mt7996_dev *dev) 878 + { 879 + return 0; 880 + } 881 + 882 + static inline int mt7996_npu_hw_stop(struct mt7996_dev *dev) 883 + { 884 + return 0; 885 + } 886 + 887 + static inline int mt7996_npu_rx_queues_init(struct mt7996_dev *dev) 888 + { 889 + return 0; 890 + } 891 + #endif /* CONFIG_MT7996_NPU */ 880 892 881 893 #endif
+352
drivers/net/wireless/mediatek/mt76/mt7996/npu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2025 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + #include <linux/kernel.h> 7 + #include <linux/soc/airoha/airoha_offload.h> 8 + 9 + #include "mt7996.h" 10 + 11 + static int mt7996_npu_offload_init(struct mt7996_dev *dev, 12 + struct airoha_npu *npu) 13 + { 14 + phys_addr_t phy_addr = dev->mt76.mmio.phy_addr; 15 + u32 val, hif1_ofs = 0, dma_addr; 16 + int i, err; 17 + 18 + err = mt76_npu_get_msg(npu, 0, WLAN_FUNC_GET_WAIT_NPU_VERSION, 19 + &val, GFP_KERNEL); 20 + if (err) { 21 + dev_warn(dev->mt76.dev, "failed getting NPU fw version\n"); 22 + return err; 23 + } 24 + 25 + dev_info(dev->mt76.dev, "NPU version: %0d.%d\n", 26 + (val >> 16) & 0xffff, val & 0xffff); 27 + 28 + err = mt76_npu_send_msg(npu, 0, WLAN_FUNC_SET_WAIT_PCIE_PORT_TYPE, 29 + dev->mt76.mmio.npu_type, GFP_KERNEL); 30 + if (err) { 31 + dev_warn(dev->mt76.dev, 32 + "failed setting NPU wlan PCIe port type\n"); 33 + return err; 34 + } 35 + 36 + if (dev->hif2) 37 + hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0); 38 + 39 + for (i = MT_BAND0; i < MT_BAND2; i++) { 40 + dma_addr = phy_addr; 41 + if (i) 42 + dma_addr += MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND1) + 0x90 + 43 + hif1_ofs; 44 + else 45 + dma_addr += MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0) + 0x80; 46 + 47 + err = mt76_npu_send_msg(npu, i, WLAN_FUNC_SET_WAIT_PCIE_ADDR, 48 + dma_addr, GFP_KERNEL); 49 + if (err) { 50 + dev_warn(dev->mt76.dev, 51 + "failed setting NPU wlan PCIe desc addr\n"); 52 + return err; 53 + } 54 + 55 + err = mt76_npu_send_msg(npu, i, WLAN_FUNC_SET_WAIT_DESC, 56 + MT7996_RX_RING_SIZE, GFP_KERNEL); 57 + if (err) { 58 + dev_warn(dev->mt76.dev, 59 + "failed setting NPU wlan PCIe desc size\n"); 60 + return err; 61 + } 62 + 63 + dma_addr = phy_addr; 64 + if (i) 65 + dma_addr += MT_TXQ_RING_BASE(0) + 0x150 + hif1_ofs; 66 + else 67 + dma_addr += MT_TXQ_RING_BASE(0) + 0x120; 68 + 69 + err = mt76_npu_send_msg(npu, i, 70 + WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, 71 + dma_addr, GFP_KERNEL); 72 + if (err) { 73 + dev_warn(dev->mt76.dev, 74 + "failed setting NPU wlan tx desc addr\n"); 75 + return err; 76 + } 77 + } 78 + 79 + err = mt76_npu_send_msg(npu, 9, WLAN_FUNC_SET_WAIT_PCIE_ADDR, 80 + phy_addr + MT_RXQ_RRO_AP_RING_BASE, 81 + GFP_KERNEL); 82 + if (err) { 83 + dev_warn(dev->mt76.dev, 84 + "failed setting NPU wlan rxdmad_c addr\n"); 85 + return err; 86 + } 87 + 88 + err = mt76_npu_send_msg(npu, 9, WLAN_FUNC_SET_WAIT_DESC, 89 + MT7996_RX_RING_SIZE, GFP_KERNEL); 90 + if (err) { 91 + dev_warn(dev->mt76.dev, 92 + "failed setting NPU wlan rxdmad_c desc size\n"); 93 + return err; 94 + } 95 + 96 + err = mt76_npu_send_msg(npu, 2, WLAN_FUNC_SET_WAIT_TX_RING_PCIE_ADDR, 97 + phy_addr + MT_RRO_ACK_SN_CTRL, GFP_KERNEL); 98 + if (err) { 99 + dev_warn(dev->mt76.dev, 100 + "failed setting NPU wlan rro_ack_sn desc addr\n"); 101 + return err; 102 + } 103 + 104 + err = mt76_npu_send_msg(npu, 0, WLAN_FUNC_SET_WAIT_TOKEN_ID_SIZE, 105 + MT7996_HW_TOKEN_SIZE, GFP_KERNEL); 106 + if (err) 107 + return err; 108 + 109 + dev->mt76.token_start = MT7996_HW_TOKEN_SIZE; 110 + 111 + return 0; 112 + } 113 + 114 + static int mt7996_npu_rxd_init(struct mt7996_dev *dev, struct airoha_npu *npu) 115 + { 116 + u32 val; 117 + int err; 118 + 119 + err = mt76_npu_get_msg(npu, 0, WLAN_FUNC_GET_WAIT_RXDESC_BASE, 120 + &val, GFP_KERNEL); 121 + if (err) { 122 + dev_warn(dev->mt76.dev, 123 + "failed retriving NPU wlan rx ring0 addr\n"); 124 + return err; 125 + } 126 + writel(val, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0].regs->desc_base); 127 + 128 + err = mt76_npu_get_msg(npu, 1, WLAN_FUNC_GET_WAIT_RXDESC_BASE, 129 + &val, GFP_KERNEL); 130 + if (err) { 131 + dev_warn(dev->mt76.dev, 132 + "failed retriving NPU wlan rx ring1 addr\n"); 133 + return err; 134 + } 135 + writel(val, &dev->mt76.q_rx[MT_RXQ_RRO_BAND1].regs->desc_base); 136 + 137 + err = mt76_npu_get_msg(npu, 9, WLAN_FUNC_GET_WAIT_RXDESC_BASE, 138 + &val, GFP_KERNEL); 139 + if (err) { 140 + dev_warn(dev->mt76.dev, 141 + "failed retriving NPU wlan rxdmad_c ring addr\n"); 142 + return err; 143 + } 144 + writel(val, &dev->mt76.q_rx[MT_RXQ_RRO_RXDMAD_C].regs->desc_base); 145 + 146 + return 0; 147 + } 148 + 149 + static int mt7996_npu_txd_init(struct mt7996_dev *dev, struct airoha_npu *npu) 150 + { 151 + int i, err; 152 + 153 + for (i = MT_BAND0; i < MT_BAND2; i++) { 154 + dma_addr_t dma_addr; 155 + u32 val; 156 + 157 + err = mt76_npu_get_msg(npu, i + 5, 158 + WLAN_FUNC_GET_WAIT_RXDESC_BASE, 159 + &val, GFP_KERNEL); 160 + if (err) { 161 + dev_warn(dev->mt76.dev, 162 + "failed retriving NPU wlan tx ring addr\n"); 163 + return err; 164 + } 165 + writel(val, &dev->mt76.phys[i]->q_tx[0]->regs->desc_base); 166 + 167 + if (!dmam_alloc_coherent(dev->mt76.dma_dev, 168 + 256 * MT7996_TX_RING_SIZE, 169 + &dma_addr, GFP_KERNEL)) 170 + return -ENOMEM; 171 + 172 + err = mt76_npu_send_msg(npu, i, 173 + WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, 174 + dma_addr, GFP_KERNEL); 175 + if (err) { 176 + dev_warn(dev->mt76.dev, 177 + "failed setting NPU wlan queue buf addr\n"); 178 + return err; 179 + } 180 + 181 + if (!dmam_alloc_coherent(dev->mt76.dma_dev, 182 + 256 * MT7996_TX_RING_SIZE, 183 + &dma_addr, GFP_KERNEL)) 184 + return -ENOMEM; 185 + 186 + err = mt76_npu_send_msg(npu, i + 5, 187 + WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, 188 + dma_addr, GFP_KERNEL); 189 + if (err) { 190 + dev_warn(dev->mt76.dev, 191 + "failed setting NPU wlan tx buf addr\n"); 192 + return err; 193 + } 194 + 195 + if (!dmam_alloc_coherent(dev->mt76.dma_dev, 256 * 1024, 196 + &dma_addr, GFP_KERNEL)) 197 + return -ENOMEM; 198 + 199 + err = mt76_npu_send_msg(npu, i + 10, 200 + WLAN_FUNC_SET_WAIT_TX_BUF_SPACE_HW_BASE, 201 + dma_addr, GFP_KERNEL); 202 + if (err) { 203 + dev_warn(dev->mt76.dev, 204 + "failed setting NPU wlan tx buf base\n"); 205 + return err; 206 + } 207 + } 208 + 209 + return 0; 210 + } 211 + 212 + static int mt7996_npu_rx_event_init(struct mt7996_dev *dev, 213 + struct airoha_npu *npu) 214 + { 215 + struct mt76_queue *q = &dev->mt76.q_rx[MT_RXQ_MAIN_WA]; 216 + phys_addr_t phy_addr = dev->mt76.mmio.phy_addr; 217 + int err; 218 + 219 + err = mt76_npu_send_msg(npu, 0, 220 + WLAN_FUNC_SET_WAIT_RX_RING_FOR_TXDONE_HW_BASE, 221 + q->desc_dma, GFP_KERNEL); 222 + if (err) { 223 + dev_warn(dev->mt76.dev, 224 + "failed setting NPU wlan tx-done ring\n"); 225 + return err; 226 + } 227 + 228 + err = mt76_npu_send_msg(npu, 10, WLAN_FUNC_SET_WAIT_DESC, 229 + MT7996_RX_MCU_RING_SIZE, GFP_KERNEL); 230 + if (err) { 231 + dev_warn(dev->mt76.dev, 232 + "failed setting NPU wlan descriptors\n"); 233 + return err; 234 + } 235 + 236 + phy_addr += MT_RXQ_RING_BASE(MT_RXQ_MAIN_WA) + 0x20; 237 + err = mt76_npu_send_msg(npu, 10, WLAN_FUNC_SET_WAIT_PCIE_ADDR, 238 + phy_addr, GFP_KERNEL); 239 + if (err) 240 + dev_warn(dev->mt76.dev, 241 + "failed setting NPU wlan rx pcie address\n"); 242 + return err; 243 + } 244 + 245 + static int mt7996_npu_tx_done_init(struct mt7996_dev *dev, 246 + struct airoha_npu *npu) 247 + { 248 + int err; 249 + 250 + err = mt76_npu_send_msg(npu, 2, WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 251 + 0, GFP_KERNEL); 252 + if (err) { 253 + dev_warn(dev->mt76.dev, "failed setting NPU wlan txrx addr2\n"); 254 + return err; 255 + } 256 + 257 + err = mt76_npu_send_msg(npu, 7, WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 258 + 0, GFP_KERNEL); 259 + if (err) 260 + dev_warn(dev->mt76.dev, "failed setting NPU wlan txrx addr7\n"); 261 + 262 + return err; 263 + } 264 + 265 + int mt7996_npu_rx_queues_init(struct mt7996_dev *dev) 266 + { 267 + int err; 268 + 269 + if (!mt76_npu_device_active(&dev->mt76)) 270 + return 0; 271 + 272 + err = mt76_npu_rx_queue_init(&dev->mt76, 273 + &dev->mt76.q_rx[MT_RXQ_NPU0]); 274 + if (err) 275 + return err; 276 + 277 + return mt76_npu_rx_queue_init(&dev->mt76, 278 + &dev->mt76.q_rx[MT_RXQ_NPU1]); 279 + } 280 + 281 + int mt7996_npu_hw_init(struct mt7996_dev *dev) 282 + { 283 + struct airoha_npu *npu; 284 + int i, err = 0; 285 + 286 + mutex_lock(&dev->mt76.mutex); 287 + 288 + npu = rcu_dereference_protected(dev->mt76.mmio.npu, &dev->mt76.mutex); 289 + if (!npu) 290 + goto unlock; 291 + 292 + err = mt7996_npu_offload_init(dev, npu); 293 + if (err) 294 + goto unlock; 295 + 296 + err = mt7996_npu_rxd_init(dev, npu); 297 + if (err) 298 + goto unlock; 299 + 300 + err = mt7996_npu_txd_init(dev, npu); 301 + if (err) 302 + goto unlock; 303 + 304 + err = mt7996_npu_rx_event_init(dev, npu); 305 + if (err) 306 + goto unlock; 307 + 308 + err = mt7996_npu_tx_done_init(dev, npu); 309 + if (err) 310 + goto unlock; 311 + 312 + for (i = MT_RXQ_NPU0; i <= MT_RXQ_NPU1; i++) 313 + airoha_npu_wlan_enable_irq(npu, i - MT_RXQ_NPU0); 314 + unlock: 315 + mutex_unlock(&dev->mt76.mutex); 316 + 317 + return err; 318 + } 319 + 320 + int mt7996_npu_hw_stop(struct mt7996_dev *dev) 321 + { 322 + struct airoha_npu *npu; 323 + int i, err; 324 + u32 info; 325 + 326 + npu = rcu_dereference_protected(dev->mt76.mmio.npu, &dev->mt76.mutex); 327 + if (!npu) 328 + return 0; 329 + 330 + err = mt76_npu_send_msg(npu, 4, WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 331 + 0, GFP_KERNEL); 332 + if (err) 333 + return err; 334 + 335 + for (i = 0; i < 10; i++) { 336 + err = mt76_npu_get_msg(npu, 3, WLAN_FUNC_GET_WAIT_NPU_INFO, 337 + &info, GFP_KERNEL); 338 + if (err) 339 + continue; 340 + 341 + if (info) { 342 + err = -ETIMEDOUT; 343 + continue; 344 + } 345 + } 346 + 347 + if (!err) 348 + err = mt76_npu_send_msg(npu, 6, 349 + WLAN_FUNC_SET_WAIT_INODE_TXRX_REG_ADDR, 350 + 0, GFP_KERNEL); 351 + return err; 352 + }
+5 -2
drivers/net/wireless/mediatek/mt76/mt7996/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */ ··· 140 140 hif2 = mt7996_pci_init_hif2(pdev); 141 141 dev->hif2 = hif2; 142 142 143 + mt76_npu_init(mdev, pci_resource_start(pdev, 0), 144 + pdev->bus && pci_domain_nr(pdev->bus) ? 3 : 2); 145 + 143 146 ret = mt7996_mmio_wed_init(dev, pdev, false, &irq); 144 147 if (ret < 0) 145 148 goto free_wed_or_irq_vector; ··· 161 158 goto free_wed_or_irq_vector; 162 159 163 160 mt76_wr(dev, MT_INT_MASK_CSR, 0); 164 - /* master switch of PCIe tnterrupt enable */ 161 + /* master switch of PCIe interrupt enable */ 165 162 mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff); 166 163 167 164 if (hif2) {
+1 -1
drivers/net/wireless/mediatek/mt76/mt7996/regs.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2022 MediaTek Inc. 4 4 */
+501
drivers/net/wireless/mediatek/mt76/npu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2025 AIROHA Inc 4 + * Author: Lorenzo Bianconi <lorenzo@kernel.org> 5 + */ 6 + #include <linux/kernel.h> 7 + #include <net/flow_offload.h> 8 + #include <net/pkt_cls.h> 9 + 10 + #include "mt76.h" 11 + #include "dma.h" 12 + #include "mt76_connac.h" 13 + 14 + #define MT76_NPU_RX_BUF_SIZE (1800 + \ 15 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) 16 + 17 + int mt76_npu_fill_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) 18 + { 19 + int nframes = 0; 20 + 21 + while (q->queued < q->ndesc - 1) { 22 + struct airoha_npu_rx_dma_desc *desc = (void *)q->desc; 23 + struct mt76_queue_entry *e = &q->entry[q->head]; 24 + struct page *page; 25 + int offset; 26 + 27 + e->buf = mt76_get_page_pool_buf(q, &offset, q->buf_size); 28 + if (!e->buf) 29 + break; 30 + 31 + e->dma_len[0] = SKB_WITH_OVERHEAD(q->buf_size); 32 + page = virt_to_head_page(e->buf); 33 + e->dma_addr[0] = page_pool_get_dma_addr(page) + offset; 34 + 35 + memset(&desc[q->head], 0, sizeof(*desc)); 36 + desc[q->head].addr = e->dma_addr[0]; 37 + 38 + q->head = (q->head + 1) % q->ndesc; 39 + q->queued++; 40 + nframes++; 41 + } 42 + 43 + return nframes; 44 + } 45 + 46 + void mt76_npu_queue_cleanup(struct mt76_dev *dev, struct mt76_queue *q) 47 + { 48 + spin_lock_bh(&q->lock); 49 + while (q->queued > 0) { 50 + struct mt76_queue_entry *e = &q->entry[q->tail]; 51 + 52 + dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0], 53 + e->dma_len[0], 54 + page_pool_get_dma_dir(q->page_pool)); 55 + mt76_put_page_pool_buf(e->buf, false); 56 + q->tail = (q->tail + 1) % q->ndesc; 57 + q->queued--; 58 + } 59 + spin_unlock_bh(&q->lock); 60 + } 61 + 62 + static struct sk_buff *mt76_npu_dequeue(struct mt76_dev *dev, 63 + struct mt76_queue *q, 64 + u32 *info) 65 + { 66 + struct airoha_npu_rx_dma_desc *desc = (void *)q->desc; 67 + int i, nframes, index = q->tail; 68 + struct sk_buff *skb = NULL; 69 + 70 + nframes = FIELD_GET(NPU_RX_DMA_PKT_COUNT_MASK, desc[index].info); 71 + nframes = max_t(int, nframes, 1); 72 + 73 + for (i = 0; i < nframes; i++) { 74 + struct mt76_queue_entry *e = &q->entry[index]; 75 + int len = FIELD_GET(NPU_RX_DMA_DESC_CUR_LEN_MASK, 76 + desc[index].ctrl); 77 + 78 + if (!FIELD_GET(NPU_RX_DMA_DESC_DONE_MASK, desc[index].ctrl)) { 79 + dev_kfree_skb(skb); 80 + return NULL; 81 + } 82 + 83 + dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0], 84 + e->dma_len[0], 85 + page_pool_get_dma_dir(q->page_pool)); 86 + 87 + if (!skb) { 88 + skb = napi_build_skb(e->buf, q->buf_size); 89 + if (!skb) 90 + return NULL; 91 + 92 + __skb_put(skb, len); 93 + skb_reset_mac_header(skb); 94 + skb_mark_for_recycle(skb); 95 + } else { 96 + struct skb_shared_info *shinfo = skb_shinfo(skb); 97 + struct page *page = virt_to_head_page(e->buf); 98 + int nr_frags = shinfo->nr_frags; 99 + 100 + if (nr_frags < ARRAY_SIZE(shinfo->frags)) 101 + skb_add_rx_frag(skb, nr_frags, page, 102 + e->buf - page_address(page), 103 + len, q->buf_size); 104 + } 105 + 106 + *info = desc[index].info; 107 + index = (index + 1) % q->ndesc; 108 + } 109 + q->tail = index; 110 + q->queued -= i; 111 + Q_WRITE(q, dma_idx, q->tail); 112 + 113 + return skb; 114 + } 115 + 116 + void mt76_npu_check_ppe(struct mt76_dev *dev, struct sk_buff *skb, 117 + u32 info) 118 + { 119 + struct airoha_ppe_dev *ppe_dev; 120 + u16 reason, hash; 121 + 122 + if (!mt76_npu_device_active(dev)) 123 + return; 124 + 125 + rcu_read_lock(); 126 + 127 + ppe_dev = rcu_dereference(dev->mmio.ppe_dev); 128 + if (!ppe_dev) 129 + goto out; 130 + 131 + hash = FIELD_GET(NPU_RX_DMA_FOE_ID_MASK, info); 132 + skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); 133 + 134 + reason = FIELD_GET(NPU_RX_DMA_CRSN_MASK, info); 135 + if (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) { 136 + skb_set_mac_header(skb, 0); 137 + airoha_ppe_dev_check_skb(ppe_dev, skb, hash, true); 138 + } 139 + out: 140 + rcu_read_unlock(); 141 + } 142 + EXPORT_SYMBOL_GPL(mt76_npu_check_ppe); 143 + 144 + static int mt76_npu_rx_poll(struct napi_struct *napi, int budget) 145 + { 146 + struct mt76_dev *dev = mt76_priv(napi->dev); 147 + enum mt76_rxq_id qid = napi - dev->napi; 148 + struct airoha_npu *npu; 149 + int done = 0; 150 + 151 + rcu_read_lock(); 152 + 153 + npu = rcu_dereference(dev->mmio.npu); 154 + if (!npu) 155 + goto out; 156 + 157 + while (done < budget) { 158 + struct sk_buff *skb; 159 + u32 info = 0; 160 + 161 + skb = mt76_npu_dequeue(dev, &dev->q_rx[qid], &info); 162 + if (!skb) 163 + break; 164 + 165 + dev->drv->rx_skb(dev, qid, skb, &info); 166 + mt76_rx_poll_complete(dev, qid, napi); 167 + done++; 168 + } 169 + 170 + mt76_npu_fill_rx_queue(dev, &dev->q_rx[qid]); 171 + out: 172 + if (done < budget && napi_complete(napi)) 173 + dev->drv->rx_poll_complete(dev, qid); 174 + 175 + rcu_read_unlock(); 176 + 177 + return done; 178 + } 179 + 180 + static irqreturn_t mt76_npu_irq_handler(int irq, void *q_instance) 181 + { 182 + struct mt76_queue *q = q_instance; 183 + struct mt76_dev *dev = q->dev; 184 + int qid = q - &dev->q_rx[0]; 185 + int index = qid - MT_RXQ_NPU0; 186 + struct airoha_npu *npu; 187 + u32 status; 188 + 189 + rcu_read_lock(); 190 + 191 + npu = rcu_dereference(dev->mmio.npu); 192 + if (!npu) 193 + goto out; 194 + 195 + status = airoha_npu_wlan_get_irq_status(npu, index); 196 + airoha_npu_wlan_set_irq_status(npu, status); 197 + 198 + airoha_npu_wlan_disable_irq(npu, index); 199 + napi_schedule(&dev->napi[qid]); 200 + out: 201 + rcu_read_unlock(); 202 + 203 + return IRQ_HANDLED; 204 + } 205 + 206 + int mt76_npu_dma_add_buf(struct mt76_phy *phy, struct mt76_queue *q, 207 + struct sk_buff *skb, struct mt76_queue_buf *buf, 208 + void *txwi_ptr) 209 + { 210 + u16 txwi_len = min_t(u16, phy->dev->drv->txwi_size, NPU_TXWI_LEN); 211 + struct airoha_npu_tx_dma_desc *desc = (void *)q->desc; 212 + int ret; 213 + 214 + /* TODO: Take into account unlinear skbs */ 215 + memcpy(desc[q->head].txwi, txwi_ptr, txwi_len); 216 + desc[q->head].addr = buf->addr; 217 + desc[q->head].ctrl = FIELD_PREP(NPU_TX_DMA_DESC_VEND_LEN_MASK, txwi_len) | 218 + FIELD_PREP(NPU_TX_DMA_DESC_LEN_MASK, skb->len) | 219 + NPU_TX_DMA_DESC_DONE_MASK; 220 + 221 + ret = q->head; 222 + q->entry[q->head].skip_buf0 = true; 223 + q->entry[q->head].skip_buf1 = true; 224 + q->entry[q->head].txwi = NULL; 225 + q->entry[q->head].skb = NULL; 226 + q->entry[q->head].wcid = 0xffff; 227 + 228 + q->head = (q->head + 1) % q->ndesc; 229 + q->queued++; 230 + 231 + return ret; 232 + } 233 + 234 + void mt76_npu_txdesc_cleanup(struct mt76_queue *q, int index) 235 + { 236 + struct airoha_npu_tx_dma_desc *desc = (void *)q->desc; 237 + 238 + if (!mt76_queue_is_npu_tx(q)) 239 + return; 240 + 241 + desc[index].ctrl &= ~NPU_TX_DMA_DESC_DONE_MASK; 242 + } 243 + 244 + void mt76_npu_queue_setup(struct mt76_dev *dev, struct mt76_queue *q) 245 + { 246 + int qid = FIELD_GET(MT_QFLAG_WED_RING, q->flags); 247 + bool xmit = mt76_queue_is_npu_tx(q); 248 + struct airoha_npu *npu; 249 + 250 + if (!mt76_queue_is_npu(q)) 251 + return; 252 + 253 + npu = rcu_dereference_protected(dev->mmio.npu, &dev->mutex); 254 + if (npu) 255 + q->wed_regs = airoha_npu_wlan_get_queue_addr(npu, qid, xmit); 256 + } 257 + 258 + int mt76_npu_rx_queue_init(struct mt76_dev *dev, struct mt76_queue *q) 259 + { 260 + int err, irq, qid = q - &dev->q_rx[0]; 261 + int size, index = qid - MT_RXQ_NPU0; 262 + struct airoha_npu *npu; 263 + const char *name; 264 + 265 + mutex_lock(&dev->mutex); 266 + 267 + npu = rcu_dereference_protected(dev->mmio.npu, &dev->mutex); 268 + irq = npu && index < ARRAY_SIZE(npu->irqs) ? npu->irqs[index] 269 + : -EINVAL; 270 + if (irq < 0) { 271 + err = irq; 272 + goto out; 273 + } 274 + 275 + q->flags = MT_NPU_Q_RX(index); 276 + size = qid == MT_RXQ_NPU1 ? NPU_RX1_DESC_NUM : NPU_RX0_DESC_NUM; 277 + err = dev->queue_ops->alloc(dev, q, 0, size, 278 + MT76_NPU_RX_BUF_SIZE, 0); 279 + if (err) 280 + goto out; 281 + 282 + name = devm_kasprintf(dev->dev, GFP_KERNEL, "mt76-npu.%d", index); 283 + if (!name) { 284 + err = -ENOMEM; 285 + goto out; 286 + } 287 + 288 + err = devm_request_irq(dev->dev, irq, mt76_npu_irq_handler, 289 + IRQF_SHARED, name, q); 290 + if (err) 291 + goto out; 292 + 293 + netif_napi_add(dev->napi_dev, &dev->napi[qid], mt76_npu_rx_poll); 294 + mt76_npu_fill_rx_queue(dev, q); 295 + napi_enable(&dev->napi[qid]); 296 + out: 297 + mutex_unlock(&dev->mutex); 298 + 299 + return err; 300 + } 301 + EXPORT_SYMBOL_GPL(mt76_npu_rx_queue_init); 302 + 303 + static int mt76_npu_setup_tc_block_cb(enum tc_setup_type type, 304 + void *type_data, void *cb_priv) 305 + { 306 + struct mt76_phy *phy = cb_priv; 307 + struct mt76_dev *dev = phy->dev; 308 + struct airoha_ppe_dev *ppe_dev; 309 + int err = -EOPNOTSUPP; 310 + 311 + if (type != TC_SETUP_CLSFLOWER) 312 + return -EOPNOTSUPP; 313 + 314 + mutex_lock(&dev->mutex); 315 + 316 + ppe_dev = rcu_dereference_protected(dev->mmio.ppe_dev, &dev->mutex); 317 + if (ppe_dev) 318 + err = airoha_ppe_dev_setup_tc_block_cb(ppe_dev, type_data); 319 + 320 + mutex_unlock(&dev->mutex); 321 + 322 + return err; 323 + } 324 + 325 + static int mt76_npu_setup_tc_block(struct mt76_phy *phy, 326 + struct net_device *dev, 327 + struct flow_block_offload *f) 328 + { 329 + flow_setup_cb_t *cb = mt76_npu_setup_tc_block_cb; 330 + static LIST_HEAD(block_cb_list); 331 + struct flow_block_cb *block_cb; 332 + 333 + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) 334 + return -EOPNOTSUPP; 335 + 336 + if (!tc_can_offload(dev)) 337 + return -EOPNOTSUPP; 338 + 339 + f->driver_block_list = &block_cb_list; 340 + switch (f->command) { 341 + case FLOW_BLOCK_BIND: 342 + block_cb = flow_block_cb_lookup(f->block, cb, dev); 343 + if (block_cb) { 344 + flow_block_cb_incref(block_cb); 345 + return 0; 346 + } 347 + 348 + block_cb = flow_block_cb_alloc(cb, dev, phy, NULL); 349 + if (IS_ERR(block_cb)) 350 + return PTR_ERR(block_cb); 351 + 352 + flow_block_cb_incref(block_cb); 353 + flow_block_cb_add(block_cb, f); 354 + list_add_tail(&block_cb->driver_list, &block_cb_list); 355 + return 0; 356 + case FLOW_BLOCK_UNBIND: 357 + block_cb = flow_block_cb_lookup(f->block, cb, dev); 358 + if (!block_cb) 359 + return -ENOENT; 360 + 361 + if (!flow_block_cb_decref(block_cb)) { 362 + flow_block_cb_remove(block_cb, f); 363 + list_del(&block_cb->driver_list); 364 + } 365 + return 0; 366 + default: 367 + return -EOPNOTSUPP; 368 + } 369 + } 370 + 371 + int mt76_npu_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 372 + struct net_device *dev, enum tc_setup_type type, 373 + void *type_data) 374 + { 375 + struct mt76_phy *phy = hw->priv; 376 + 377 + if (!tc_can_offload(dev)) 378 + return -EOPNOTSUPP; 379 + 380 + if (!mt76_npu_device_active(phy->dev)) 381 + return -EOPNOTSUPP; 382 + 383 + switch (type) { 384 + case TC_SETUP_BLOCK: 385 + case TC_SETUP_FT: 386 + return mt76_npu_setup_tc_block(phy, dev, type_data); 387 + default: 388 + return -EOPNOTSUPP; 389 + } 390 + } 391 + EXPORT_SYMBOL_GPL(mt76_npu_net_setup_tc); 392 + 393 + void mt76_npu_disable_irqs(struct mt76_dev *dev) 394 + { 395 + struct airoha_npu *npu; 396 + int i; 397 + 398 + rcu_read_lock(); 399 + 400 + npu = rcu_dereference(dev->mmio.npu); 401 + if (!npu) 402 + goto unlock; 403 + 404 + for (i = MT_RXQ_NPU0; i <= MT_RXQ_NPU1; i++) { 405 + int qid = i - MT_RXQ_NPU0; 406 + u32 status; 407 + 408 + status = airoha_npu_wlan_get_irq_status(npu, qid); 409 + airoha_npu_wlan_set_irq_status(npu, status); 410 + airoha_npu_wlan_disable_irq(npu, qid); 411 + } 412 + unlock: 413 + rcu_read_unlock(); 414 + } 415 + EXPORT_SYMBOL_GPL(mt76_npu_disable_irqs); 416 + 417 + int mt76_npu_init(struct mt76_dev *dev, phys_addr_t phy_addr, int type) 418 + { 419 + struct airoha_ppe_dev *ppe_dev; 420 + struct airoha_npu *npu; 421 + int err = 0; 422 + 423 + /* NPU offloading is only supported by MT7992 */ 424 + if (!is_mt7992(dev)) 425 + return 0; 426 + 427 + mutex_lock(&dev->mutex); 428 + 429 + npu = airoha_npu_get(dev->dev); 430 + if (IS_ERR(npu)) { 431 + request_module("airoha-npu"); 432 + npu = airoha_npu_get(dev->dev); 433 + } 434 + 435 + if (IS_ERR(npu)) { 436 + err = PTR_ERR(npu); 437 + goto error_unlock; 438 + } 439 + 440 + ppe_dev = airoha_ppe_get_dev(dev->dev); 441 + if (IS_ERR(ppe_dev)) { 442 + request_module("airoha-eth"); 443 + ppe_dev = airoha_ppe_get_dev(dev->dev); 444 + } 445 + 446 + if (IS_ERR(ppe_dev)) { 447 + err = PTR_ERR(ppe_dev); 448 + goto error_npu_put; 449 + } 450 + 451 + err = airoha_npu_wlan_init_reserved_memory(npu); 452 + if (err) 453 + goto error_ppe_put; 454 + 455 + dev->dma_dev = npu->dev; 456 + dev->mmio.phy_addr = phy_addr; 457 + dev->mmio.npu_type = type; 458 + /* NPU offloading requires HW-RRO for RX packet reordering. */ 459 + dev->hwrro_mode = MT76_HWRRO_V3_1; 460 + 461 + rcu_assign_pointer(dev->mmio.npu, npu); 462 + rcu_assign_pointer(dev->mmio.ppe_dev, ppe_dev); 463 + synchronize_rcu(); 464 + 465 + mutex_unlock(&dev->mutex); 466 + 467 + return 0; 468 + 469 + error_ppe_put: 470 + airoha_ppe_put_dev(ppe_dev); 471 + error_npu_put: 472 + airoha_npu_put(npu); 473 + error_unlock: 474 + mutex_unlock(&dev->mutex); 475 + 476 + return err; 477 + } 478 + EXPORT_SYMBOL_GPL(mt76_npu_init); 479 + 480 + void mt76_npu_deinit(struct mt76_dev *dev) 481 + { 482 + struct airoha_ppe_dev *ppe_dev; 483 + struct airoha_npu *npu; 484 + 485 + mutex_lock(&dev->mutex); 486 + 487 + npu = rcu_replace_pointer(dev->mmio.npu, NULL, 488 + lockdep_is_held(&dev->mutex)); 489 + if (npu) 490 + airoha_npu_put(npu); 491 + 492 + ppe_dev = rcu_replace_pointer(dev->mmio.ppe_dev, NULL, 493 + lockdep_is_held(&dev->mutex)); 494 + if (ppe_dev) 495 + airoha_ppe_put_dev(ppe_dev); 496 + 497 + mutex_unlock(&dev->mutex); 498 + 499 + mt76_npu_queue_cleanup(dev, &dev->q_rx[MT_RXQ_NPU0]); 500 + mt76_npu_queue_cleanup(dev, &dev->q_rx[MT_RXQ_NPU1]); 501 + }
+1 -1
drivers/net/wireless/mediatek/mt76/pci.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/scan.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2024 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/sdio.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * This file is written based on mt76/usb.c.
+1 -1
drivers/net/wireless/mediatek/mt76/sdio.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * Author: Sean Wang <sean.wang@mediatek.com>
+1 -1
drivers/net/wireless/mediatek/mt76/sdio_txrx.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 MediaTek Inc. 3 3 * 4 4 * Author: Felix Fietkau <nbd@nbd.name>
+1 -1
drivers/net/wireless/mediatek/mt76/testmode.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */ 3 3 4 4 #include <linux/random.h>
+1 -1
drivers/net/wireless/mediatek/mt76/testmode.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/trace.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/trace.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+5 -3
drivers/net/wireless/mediatek/mt76/tx.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */ ··· 847 847 848 848 spin_lock_bh(&dev->token_lock); 849 849 850 - token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC); 851 - if (token >= 0) 850 + token = idr_alloc(&dev->token, *ptxwi, dev->token_start, 851 + dev->token_start + dev->token_size, 852 + GFP_ATOMIC); 853 + if (token >= dev->token_start) 852 854 dev->token_count++; 853 855 854 856 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+1 -1
drivers/net/wireless/mediatek/mt76/usb.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/usb_trace.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/usb_trace.h
··· 1 - /* SPDX-License-Identifier: ISC */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 4 */
+1 -1
drivers/net/wireless/mediatek/mt76/util.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 4 */
+1 -2
drivers/net/wireless/mediatek/mt76/util.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 1 + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2 2 /* 3 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 - * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> 5 4 */ 6 5 7 6 #ifndef __MT76_UTIL_H
+6 -6
drivers/net/wireless/mediatek/mt76/wed.c
··· 1 - // SPDX-License-Identifier: ISC 1 + // SPDX-License-Identifier: BSD-3-Clause-Clear 2 2 /* 3 3 * Copyright (C) 2023 Lorenzo Bianconi <lorenzo@kernel.org> 4 4 */ ··· 8 8 9 9 void mt76_wed_release_rx_buf(struct mtk_wed_device *wed) 10 10 { 11 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 11 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 12 12 int i; 13 13 14 14 for (i = 0; i < dev->rx_token_size; i++) { ··· 31 31 #ifdef CONFIG_NET_MEDIATEK_SOC_WED 32 32 u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size) 33 33 { 34 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 35 34 struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc; 35 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 36 36 struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN]; 37 37 struct mt76_txwi_cache *t = NULL; 38 38 int i; ··· 80 80 81 81 int mt76_wed_offload_enable(struct mtk_wed_device *wed) 82 82 { 83 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 83 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 84 84 85 85 spin_lock_bh(&dev->token_lock); 86 86 dev->token_size = wed->wlan.token_start; ··· 164 164 165 165 void mt76_wed_offload_disable(struct mtk_wed_device *wed) 166 166 { 167 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 167 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 168 168 169 169 spin_lock_bh(&dev->token_lock); 170 170 dev->token_size = dev->drv->token_size; ··· 174 174 175 175 void mt76_wed_reset_complete(struct mtk_wed_device *wed) 176 176 { 177 - struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); 177 + struct mt76_dev *dev = mt76_wed_to_dev(wed); 178 178 179 179 complete(&dev->mmio.wed_reset_complete); 180 180 }
+2 -1
drivers/net/wireless/quantenna/qtnfmac/core.c
··· 714 714 goto error; 715 715 } 716 716 717 - bus->hprio_workqueue = alloc_workqueue("QTNF_HPRI", WQ_HIGHPRI, 0); 717 + bus->hprio_workqueue = alloc_workqueue("QTNF_HPRI", 718 + WQ_HIGHPRI | WQ_PERCPU, 0); 718 719 if (!bus->hprio_workqueue) { 719 720 pr_err("failed to alloc high prio workqueue\n"); 720 721 ret = -ENOMEM;
+2 -7
drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
··· 1023 1023 dma_addr_t *mapping; 1024 1024 entry = priv->rx_ring + priv->rx_ring_sz*i; 1025 1025 if (!skb) { 1026 - dma_free_coherent(&priv->pdev->dev, 1027 - priv->rx_ring_sz * 32, 1028 - priv->rx_ring, priv->rx_ring_dma); 1029 1026 wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); 1030 1027 return -ENOMEM; 1031 1028 } ··· 1034 1037 1035 1038 if (dma_mapping_error(&priv->pdev->dev, *mapping)) { 1036 1039 kfree_skb(skb); 1037 - dma_free_coherent(&priv->pdev->dev, 1038 - priv->rx_ring_sz * 32, 1039 - priv->rx_ring, priv->rx_ring_dma); 1040 + priv->rx_buf[i] = NULL; 1040 1041 wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); 1041 1042 return -ENOMEM; 1042 1043 } ··· 1125 1130 1126 1131 ret = rtl8180_init_rx_ring(dev); 1127 1132 if (ret) 1128 - return ret; 1133 + goto err_free_rings; 1129 1134 1130 1135 for (i = 0; i < (dev->queues + 1); i++) 1131 1136 if ((ret = rtl8180_init_tx_ring(dev, i, 16)))
+19 -8
drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c
··· 338 338 spin_unlock_irqrestore(&priv->rx_queue.lock, f); 339 339 skb_put(skb, urb->actual_length); 340 340 341 - if (unlikely(urb->status)) { 342 - dev_kfree_skb_irq(skb); 343 - return; 344 - } 341 + if (unlikely(urb->status)) 342 + goto free_skb; 345 343 346 344 if (!priv->is_rtl8187b) { 347 - struct rtl8187_rx_hdr *hdr = 348 - (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); 345 + struct rtl8187_rx_hdr *hdr; 346 + 347 + if (skb->len < sizeof(struct rtl8187_rx_hdr)) 348 + goto free_skb; 349 + 350 + hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); 349 351 flags = le32_to_cpu(hdr->flags); 350 352 /* As with the RTL8187B below, the AGC is used to calculate 351 353 * signal strength. In this case, the scaling ··· 357 355 rx_status.antenna = (hdr->signal >> 7) & 1; 358 356 rx_status.mactime = le64_to_cpu(hdr->mac_time); 359 357 } else { 360 - struct rtl8187b_rx_hdr *hdr = 361 - (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); 358 + struct rtl8187b_rx_hdr *hdr; 359 + 360 + if (skb->len < sizeof(struct rtl8187b_rx_hdr)) 361 + goto free_skb; 362 + 363 + hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); 362 364 /* The Realtek datasheet for the RTL8187B shows that the RX 363 365 * header contains the following quantities: signal quality, 364 366 * RSSI, AGC, the received power in dB, and the measured SNR. ··· 415 409 skb_unlink(skb, &priv->rx_queue); 416 410 dev_kfree_skb_irq(skb); 417 411 } 412 + return; 413 + 414 + free_skb: 415 + dev_kfree_skb_irq(skb); 416 + return; 418 417 } 419 418 420 419 static int rtl8187_init_urbs(struct ieee80211_hw *dev)
+79 -1
drivers/net/wireless/realtek/rtl8xxxu/8192c.c
··· 593 593 return 0; 594 594 } 595 595 596 + static void rtl8192cu_power_off(struct rtl8xxxu_priv *priv) 597 + { 598 + u32 val32; 599 + u16 val16; 600 + u8 val8; 601 + int i; 602 + 603 + /* 604 + * Workaround for 8188RU LNA power leakage problem. 605 + */ 606 + if (priv->rtl_chip == RTL8188R) { 607 + val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM); 608 + val32 |= BIT(1); 609 + rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32); 610 + } 611 + 612 + /* _DisableRFAFEAndResetBB */ 613 + rtl8xxxu_write8(priv, REG_TXPAUSE, 0xff); 614 + rtl8xxxu_write_rfreg_mask(priv, RF_A, RF6052_REG_AC, 0xff, 0); 615 + 616 + rtl8xxxu_write8_set(priv, REG_APSD_CTRL, APSD_CTRL_OFF); 617 + rtl8xxxu_write32_set(priv, REG_FPGA0_XCD_RF_PARM, FPGA0_RF_PARM_CLK_GATE); 618 + 619 + rtl8xxxu_write8(priv, REG_SYS_FUNC, 620 + SYS_FUNC_USBA | SYS_FUNC_USBD | SYS_FUNC_BB_GLB_RSTN); 621 + rtl8xxxu_write8(priv, REG_SYS_FUNC, SYS_FUNC_USBA | SYS_FUNC_USBD); 622 + 623 + /* _ResetDigitalProcedure1 */ 624 + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_DL_READY) { 625 + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); 626 + 627 + rtl8xxxu_write8(priv, REG_FWIMR, 0x20); 628 + 629 + rtl8xxxu_write8(priv, REG_HMTFR + 3, 0x20); 630 + 631 + for (i = 0; i < 100; i++) { 632 + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 633 + if (!(val16 & SYS_FUNC_CPU_ENABLE)) 634 + break; 635 + 636 + fsleep(50); 637 + } 638 + 639 + if (i == 100) { 640 + rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, 641 + (SYS_FUNC_HWPDN | SYS_FUNC_ELDR) >> 8); 642 + msleep(10); 643 + } 644 + } 645 + 646 + val8 = (SYS_FUNC_HWPDN | SYS_FUNC_ELDR | SYS_FUNC_CPU_ENABLE) >> 8; 647 + rtl8xxxu_write8(priv, REG_SYS_FUNC + 1, val8); 648 + 649 + /* _DisableGPIO */ 650 + rtl8xxxu_write16(priv, REG_GPIO_PIN_CTRL + 2, 0); 651 + val32 = rtl8xxxu_read32(priv, REG_GPIO_PIN_CTRL) & 0xffff00ff; 652 + val32 |= (val32 & 0xff) << 8; 653 + val32 |= 0x00ff0000; 654 + rtl8xxxu_write32(priv, REG_GPIO_PIN_CTRL, val32); 655 + 656 + rtl8xxxu_write8(priv, REG_GPIO_MUXCFG + 3, 0); 657 + val16 = rtl8xxxu_read16(priv, REG_GPIO_MUXCFG + 2) & 0xff0f; 658 + val16 |= (val16 & 0xf) << 4; 659 + val16 |= 0x0780; 660 + rtl8xxxu_write16(priv, REG_GPIO_MUXCFG + 2, val16); 661 + 662 + /* _DisableAnalog */ 663 + val8 = 0x23; 664 + if (priv->vendor_umc && priv->chip_cut == 1) 665 + val8 |= BIT(3); 666 + rtl8xxxu_write8(priv, REG_SPS0_CTRL, val8); 667 + 668 + val16 = APS_FSMCO_HOST | APS_FSMCO_HW_SUSPEND | APS_FSMCO_PFM_ALDN; 669 + rtl8xxxu_write16(priv, REG_APS_FSMCO, val16); 670 + 671 + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e); 672 + } 673 + 596 674 static int rtl8192cu_led_brightness_set(struct led_classdev *led_cdev, 597 675 enum led_brightness brightness) 598 676 { ··· 696 618 .parse_efuse = rtl8192cu_parse_efuse, 697 619 .load_firmware = rtl8192cu_load_firmware, 698 620 .power_on = rtl8192cu_power_on, 699 - .power_off = rtl8xxxu_power_off, 621 + .power_off = rtl8192cu_power_off, 700 622 .read_efuse = rtl8xxxu_read_efuse, 701 623 .reset_8051 = rtl8xxxu_reset_8051, 702 624 .llt_init = rtl8xxxu_init_llt_table,
+114 -1
drivers/net/wireless/realtek/rtl8xxxu/8723a.c
··· 411 411 return ret; 412 412 } 413 413 414 + static int rtl8723au_active_to_emu(struct rtl8xxxu_priv *priv) 415 + { 416 + u8 val8; 417 + int count, ret = 0; 418 + 419 + /* Start of rtl8723AU_card_enable_flow */ 420 + /* Act to Cardemu sequence*/ 421 + /* Turn off RF */ 422 + rtl8xxxu_write8(priv, REG_RF_CTRL, 0); 423 + 424 + /* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */ 425 + val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); 426 + val8 &= ~LEDCFG2_DPDT_SELECT; 427 + rtl8xxxu_write8(priv, REG_LEDCFG2, val8); 428 + 429 + /* 0x0005[1] = 1 turn off MAC by HW state machine*/ 430 + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 431 + val8 |= BIT(1); 432 + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 433 + 434 + for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 435 + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 436 + if ((val8 & BIT(1)) == 0) 437 + break; 438 + udelay(10); 439 + } 440 + 441 + if (!count) { 442 + dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", 443 + __func__); 444 + ret = -EBUSY; 445 + goto exit; 446 + } 447 + 448 + /* 0x0000[5] = 1 analog Ips to digital, 1:isolation */ 449 + val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); 450 + val8 |= SYS_ISO_ANALOG_IPS; 451 + rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); 452 + 453 + /* 0x0020[0] = 0 disable LDOA12 MACRO block*/ 454 + val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); 455 + val8 &= ~LDOA15_ENABLE; 456 + rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); 457 + 458 + exit: 459 + return ret; 460 + } 461 + 462 + static int rtl8723au_emu_to_disabled(struct rtl8xxxu_priv *priv) 463 + { 464 + u8 val8; 465 + 466 + /* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */ 467 + rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20); 468 + 469 + /* 0x04[12:11] = 01 enable WL suspend */ 470 + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 471 + val8 &= ~BIT(4); 472 + val8 |= BIT(3); 473 + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 474 + 475 + val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 476 + val8 |= BIT(7); 477 + rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 478 + 479 + /* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */ 480 + val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2); 481 + val8 |= BIT(0); 482 + rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8); 483 + 484 + return 0; 485 + } 486 + 487 + static void rtl8723au_power_off(struct rtl8xxxu_priv *priv) 488 + { 489 + u8 val8; 490 + u16 val16; 491 + 492 + rtl8xxxu_flush_fifo(priv); 493 + 494 + rtl8xxxu_active_to_lps(priv); 495 + 496 + /* Turn off RF */ 497 + rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); 498 + 499 + /* Reset Firmware if running in RAM */ 500 + if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) 501 + rtl8xxxu_firmware_self_reset(priv); 502 + 503 + /* Reset MCU */ 504 + val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 505 + val16 &= ~SYS_FUNC_CPU_ENABLE; 506 + rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 507 + 508 + /* Reset MCU ready status */ 509 + rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); 510 + 511 + rtl8723au_active_to_emu(priv); 512 + rtl8723au_emu_to_disabled(priv); 513 + 514 + /* Reset MCU IO Wrapper */ 515 + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); 516 + val8 &= ~BIT(0); 517 + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); 518 + 519 + val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); 520 + val8 |= BIT(0); 521 + rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); 522 + 523 + /* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */ 524 + rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e); 525 + } 526 + 414 527 #define XTAL1 GENMASK(23, 18) 415 528 #define XTAL0 GENMASK(17, 12) 416 529 ··· 605 492 .parse_efuse = rtl8723au_parse_efuse, 606 493 .load_firmware = rtl8723au_load_firmware, 607 494 .power_on = rtl8723au_power_on, 608 - .power_off = rtl8xxxu_power_off, 495 + .power_off = rtl8723au_power_off, 609 496 .read_efuse = rtl8xxxu_read_efuse, 610 497 .reset_8051 = rtl8xxxu_reset_8051, 611 498 .llt_init = rtl8xxxu_init_llt_table,
+41 -147
drivers/net/wireless/realtek/rtl8xxxu/core.c
··· 20 20 #define DRIVER_NAME "rtl8xxxu" 21 21 22 22 int rtl8xxxu_debug; 23 - static bool rtl8xxxu_ht40_2g; 24 23 static bool rtl8xxxu_dma_aggregation; 25 24 static int rtl8xxxu_dma_agg_timeout = -1; 26 25 static int rtl8xxxu_dma_agg_pages = -1; ··· 44 45 45 46 module_param_named(debug, rtl8xxxu_debug, int, 0600); 46 47 MODULE_PARM_DESC(debug, "Set debug mask"); 47 - module_param_named(ht40_2g, rtl8xxxu_ht40_2g, bool, 0600); 48 - MODULE_PARM_DESC(ht40_2g, "Enable HT40 support on the 2.4GHz band"); 49 48 module_param_named(dma_aggregation, rtl8xxxu_dma_aggregation, bool, 0600); 50 49 MODULE_PARM_DESC(dma_aggregation, "Enable DMA packet aggregation"); 51 50 module_param_named(dma_agg_timeout, rtl8xxxu_dma_agg_timeout, int, 0600); ··· 1249 1252 opmode &= ~BW_OPMODE_20MHZ; 1250 1253 rtl8xxxu_write8(priv, REG_BW_OPMODE, opmode); 1251 1254 rsr &= ~RSR_RSC_BANDWIDTH_40M; 1252 - if (sec_ch_above) 1255 + if (!sec_ch_above) 1253 1256 rsr |= RSR_RSC_UPPER_SUB_CHANNEL; 1254 1257 else 1255 1258 rsr |= RSR_RSC_LOWER_SUB_CHANNEL; ··· 1318 1321 1319 1322 for (i = RF_A; i < priv->rf_paths; i++) { 1320 1323 val32 = rtl8xxxu_read_rfreg(priv, i, RF6052_REG_MODE_AG); 1321 - if (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) 1322 - val32 &= ~MODE_AG_CHANNEL_20MHZ; 1323 - else 1324 + val32 &= ~MODE_AG_BW_MASK; 1325 + if (hw->conf.chandef.width != NL80211_CHAN_WIDTH_40) 1324 1326 val32 |= MODE_AG_CHANNEL_20MHZ; 1325 1327 rtl8xxxu_write_rfreg(priv, i, RF6052_REG_MODE_AG, val32); 1326 1328 } ··· 1370 1374 hw->conf.chandef.chan->center_freq) { 1371 1375 sec_ch_above = 1; 1372 1376 channel += 2; 1377 + subchannel = 2; 1373 1378 } else { 1374 1379 sec_ch_above = 0; 1375 1380 channel -= 2; 1381 + subchannel = 1; 1376 1382 } 1377 1383 1378 1384 val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); ··· 3635 3637 rtl8xxxu_write8(priv, REG_AMPDU_MIN_SPACE, val8); 3636 3638 } 3637 3639 3638 - static int rtl8xxxu_active_to_emu(struct rtl8xxxu_priv *priv) 3639 - { 3640 - u8 val8; 3641 - int count, ret = 0; 3642 - 3643 - /* Start of rtl8723AU_card_enable_flow */ 3644 - /* Act to Cardemu sequence*/ 3645 - /* Turn off RF */ 3646 - rtl8xxxu_write8(priv, REG_RF_CTRL, 0); 3647 - 3648 - /* 0x004E[7] = 0, switch DPDT_SEL_P output from register 0x0065[2] */ 3649 - val8 = rtl8xxxu_read8(priv, REG_LEDCFG2); 3650 - val8 &= ~LEDCFG2_DPDT_SELECT; 3651 - rtl8xxxu_write8(priv, REG_LEDCFG2, val8); 3652 - 3653 - /* 0x0005[1] = 1 turn off MAC by HW state machine*/ 3654 - val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 3655 - val8 |= BIT(1); 3656 - rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 3657 - 3658 - for (count = RTL8XXXU_MAX_REG_POLL; count; count--) { 3659 - val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 3660 - if ((val8 & BIT(1)) == 0) 3661 - break; 3662 - udelay(10); 3663 - } 3664 - 3665 - if (!count) { 3666 - dev_warn(&priv->udev->dev, "%s: Disabling MAC timed out\n", 3667 - __func__); 3668 - ret = -EBUSY; 3669 - goto exit; 3670 - } 3671 - 3672 - /* 0x0000[5] = 1 analog Ips to digital, 1:isolation */ 3673 - val8 = rtl8xxxu_read8(priv, REG_SYS_ISO_CTRL); 3674 - val8 |= SYS_ISO_ANALOG_IPS; 3675 - rtl8xxxu_write8(priv, REG_SYS_ISO_CTRL, val8); 3676 - 3677 - /* 0x0020[0] = 0 disable LDOA12 MACRO block*/ 3678 - val8 = rtl8xxxu_read8(priv, REG_LDOA15_CTRL); 3679 - val8 &= ~LDOA15_ENABLE; 3680 - rtl8xxxu_write8(priv, REG_LDOA15_CTRL, val8); 3681 - 3682 - exit: 3683 - return ret; 3684 - } 3685 - 3686 3640 int rtl8xxxu_active_to_lps(struct rtl8xxxu_priv *priv) 3687 3641 { 3688 3642 u8 val8; ··· 3709 3759 val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 3710 3760 val8 &= ~(BIT(3) | BIT(4)); 3711 3761 rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 3712 - } 3713 - 3714 - static int rtl8xxxu_emu_to_disabled(struct rtl8xxxu_priv *priv) 3715 - { 3716 - u8 val8; 3717 - 3718 - /* 0x0007[7:0] = 0x20 SOP option to disable BG/MB */ 3719 - rtl8xxxu_write8(priv, REG_APS_FSMCO + 3, 0x20); 3720 - 3721 - /* 0x04[12:11] = 01 enable WL suspend */ 3722 - val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 3723 - val8 &= ~BIT(4); 3724 - val8 |= BIT(3); 3725 - rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 3726 - 3727 - val8 = rtl8xxxu_read8(priv, REG_APS_FSMCO + 1); 3728 - val8 |= BIT(7); 3729 - rtl8xxxu_write8(priv, REG_APS_FSMCO + 1, val8); 3730 - 3731 - /* 0x48[16] = 1 to enable GPIO9 as EXT wakeup */ 3732 - val8 = rtl8xxxu_read8(priv, REG_GPIO_INTM + 2); 3733 - val8 |= BIT(0); 3734 - rtl8xxxu_write8(priv, REG_GPIO_INTM + 2, val8); 3735 - 3736 - return 0; 3737 3762 } 3738 3763 3739 3764 int rtl8xxxu_flush_fifo(struct rtl8xxxu_priv *priv) ··· 3786 3861 val32 = rtl8xxxu_read32(priv, REG_TXDMA_OFFSET_CHK); 3787 3862 val32 |= TXDMA_OFFSET_DROP_DATA_EN; 3788 3863 rtl8xxxu_write32(priv, REG_TXDMA_OFFSET_CHK, val32); 3789 - } 3790 - 3791 - void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv) 3792 - { 3793 - u8 val8; 3794 - u16 val16; 3795 - u32 val32; 3796 - 3797 - /* 3798 - * Workaround for 8188RU LNA power leakage problem. 3799 - */ 3800 - if (priv->rtl_chip == RTL8188R) { 3801 - val32 = rtl8xxxu_read32(priv, REG_FPGA0_XCD_RF_PARM); 3802 - val32 |= BIT(1); 3803 - rtl8xxxu_write32(priv, REG_FPGA0_XCD_RF_PARM, val32); 3804 - } 3805 - 3806 - rtl8xxxu_flush_fifo(priv); 3807 - 3808 - rtl8xxxu_active_to_lps(priv); 3809 - 3810 - /* Turn off RF */ 3811 - rtl8xxxu_write8(priv, REG_RF_CTRL, 0x00); 3812 - 3813 - /* Reset Firmware if running in RAM */ 3814 - if (rtl8xxxu_read8(priv, REG_MCU_FW_DL) & MCU_FW_RAM_SEL) 3815 - rtl8xxxu_firmware_self_reset(priv); 3816 - 3817 - /* Reset MCU */ 3818 - val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 3819 - val16 &= ~SYS_FUNC_CPU_ENABLE; 3820 - rtl8xxxu_write16(priv, REG_SYS_FUNC, val16); 3821 - 3822 - /* Reset MCU ready status */ 3823 - rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00); 3824 - 3825 - rtl8xxxu_active_to_emu(priv); 3826 - rtl8xxxu_emu_to_disabled(priv); 3827 - 3828 - /* Reset MCU IO Wrapper */ 3829 - val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); 3830 - val8 &= ~BIT(0); 3831 - rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); 3832 - 3833 - val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1); 3834 - val8 |= BIT(0); 3835 - rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8); 3836 - 3837 - /* RSV_CTRL 0x1C[7:0] = 0x0e lock ISO/CLK/Power control register */ 3838 - rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e); 3839 3864 } 3840 3865 3841 3866 void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv, ··· 4893 5018 sgi = 1; 4894 5019 4895 5020 highest_rate = fls(ramask) - 1; 4896 - if (rtl8xxxu_ht40_2g && 4897 - (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) 5021 + if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 4898 5022 bw = RATE_INFO_BW_40; 4899 5023 else 4900 5024 bw = RATE_INFO_BW_20; ··· 5219 5345 tx_desc->txdw5 |= cpu_to_le32(TXDESC32_RETRY_LIMIT_ENABLE); 5220 5346 } 5221 5347 5222 - if (ieee80211_is_data_qos(hdr->frame_control)) 5348 + if (ieee80211_is_data_qos(hdr->frame_control)) { 5223 5349 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_QOS); 5350 + 5351 + if (conf_is_ht40(&hw->conf)) { 5352 + tx_desc->txdw4 |= cpu_to_le32(TXDESC_DATA_BW); 5353 + 5354 + if (conf_is_ht40_minus(&hw->conf)) 5355 + tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_UPPER); 5356 + else 5357 + tx_desc->txdw4 |= cpu_to_le32(TXDESC_PRIME_CH_OFF_LOWER); 5358 + } 5359 + } 5224 5360 5225 5361 if (short_preamble) 5226 5362 tx_desc->txdw4 |= cpu_to_le32(TXDESC32_SHORT_PREAMBLE); ··· 5697 5813 !rtl8xxxu_is_sta_sta(priv) && 5698 5814 (rtl8xxxu_is_packet_match_bssid(priv, hdr, 0) || 5699 5815 rtl8xxxu_is_packet_match_bssid(priv, hdr, 1)); 5700 - u8 pwdb_max = 0; 5816 + u8 pwdb_max = 0, rxsc; 5701 5817 int rx_path; 5702 5818 5703 5819 if (parse_cfo) { ··· 5712 5828 pwdb_max = max(pwdb_max, phy_stats1->pwdb[rx_path]); 5713 5829 5714 5830 rx_status->signal = pwdb_max - 110; 5831 + 5832 + if (rxmcs >= DESC_RATE_6M && rxmcs <= DESC_RATE_54M) 5833 + rxsc = phy_stats1->l_rxsc; 5834 + else 5835 + rxsc = phy_stats1->ht_rxsc; 5836 + 5837 + if (phy_stats1->rf_mode == 0 || rxsc == 1 || rxsc == 2) 5838 + rx_status->bw = RATE_INFO_BW_20; 5839 + else 5840 + rx_status->bw = RATE_INFO_BW_40; 5715 5841 } 5716 5842 5717 5843 static void jaguar2_rx_parse_phystats_type2(struct rtl8xxxu_priv *priv, ··· 6348 6454 rtl8xxxu_rx_update_rssi(priv, 6349 6455 rx_status, 6350 6456 hdr); 6457 + } else { 6458 + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; 6351 6459 } 6352 6460 6353 6461 rx_status->mactime = rx_desc->tsfl; ··· 6456 6560 rtl8xxxu_rx_update_rssi(priv, 6457 6561 rx_status, 6458 6562 hdr); 6563 + } else { 6564 + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; 6459 6565 } 6460 6566 6461 6567 rx_status->mactime = rx_desc->tsfl; ··· 7804 7906 goto err_set_intfdata; 7805 7907 } 7806 7908 7909 + if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) 7910 + rtl8xxxu_dump_efuse(priv); 7911 + 7807 7912 ret = priv->fops->parse_efuse(priv); 7808 7913 if (ret) { 7809 7914 dev_err(&udev->dev, "Fatal - failed to parse EFuse\n"); 7810 7915 goto err_set_intfdata; 7811 7916 } 7812 - 7813 - if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) 7814 - rtl8xxxu_dump_efuse(priv); 7815 7917 7816 7918 rtl8xxxu_print_chipinfo(priv); 7817 7919 ··· 7847 7949 sband->ht_cap.ht_supported = true; 7848 7950 sband->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; 7849 7951 sband->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; 7850 - sband->ht_cap.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40; 7952 + sband->ht_cap.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | 7953 + IEEE80211_HT_CAP_SUP_WIDTH_20_40; 7851 7954 memset(&sband->ht_cap.mcs, 0, sizeof(sband->ht_cap.mcs)); 7852 7955 sband->ht_cap.mcs.rx_mask[0] = 0xff; 7853 7956 sband->ht_cap.mcs.rx_mask[4] = 0x01; ··· 7857 7958 sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; 7858 7959 } 7859 7960 sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 7860 - /* 7861 - * Some APs will negotiate HT20_40 in a noisy environment leading 7862 - * to miserable performance. Rather than defaulting to this, only 7863 - * enable it if explicitly requested at module load time. 7864 - */ 7865 - if (rtl8xxxu_ht40_2g) { 7866 - dev_info(&udev->dev, "Enabling HT_20_40 on the 2.4GHz band\n"); 7867 - sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 7868 - } 7961 + 7869 7962 hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; 7870 7963 7871 7964 hw->wiphy->rts_threshold = 2347; ··· 8026 8135 .driver_info = (unsigned long)&rtl8192fu_fops}, 8027 8136 /* TP-Link TL-WN823N V2 */ 8028 8137 {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0135, 0xff, 0xff, 0xff), 8138 + .driver_info = (unsigned long)&rtl8192fu_fops}, 8139 + /* D-Link AN3U rev. A1 */ 8140 + {USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3328, 0xff, 0xff, 0xff), 8029 8141 .driver_info = (unsigned long)&rtl8192fu_fops}, 8030 8142 #ifdef CONFIG_RTL8XXXU_UNTESTED 8031 8143 /* Still supported by rtlwifi */
+1
drivers/net/wireless/realtek/rtl8xxxu/regs.h
··· 40 40 #define APS_FSMCO_SW_LPS BIT(10) 41 41 #define APS_FSMCO_HW_SUSPEND BIT(11) 42 42 #define APS_FSMCO_PCIE BIT(12) 43 + #define APS_FSMCO_HOST BIT(14) 43 44 #define APS_FSMCO_HW_POWERDOWN BIT(15) 44 45 #define APS_FSMCO_WLON_RESET BIT(16) 45 46
-1
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
··· 2078 2078 const struct rtl8xxxu_reg32val *array); 2079 2079 int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, const char *fw_name); 2080 2080 void rtl8xxxu_firmware_self_reset(struct rtl8xxxu_priv *priv); 2081 - void rtl8xxxu_power_off(struct rtl8xxxu_priv *priv); 2082 2081 void rtl8xxxu_identify_vendor_1bit(struct rtl8xxxu_priv *priv, u32 vendor); 2083 2082 void rtl8xxxu_identify_vendor_2bits(struct rtl8xxxu_priv *priv, u32 vendor); 2084 2083 void rtl8xxxu_config_endpoints_sie(struct rtl8xxxu_priv *priv);
+1 -1
drivers/net/wireless/realtek/rtlwifi/base.c
··· 445 445 struct rtl_priv *rtlpriv = rtl_priv(hw); 446 446 struct workqueue_struct *wq; 447 447 448 - wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); 448 + wq = alloc_workqueue("%s", WQ_UNBOUND, 0, rtlpriv->cfg->name); 449 449 if (!wq) 450 450 return -ENOMEM; 451 451
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c
··· 694 694 695 695 if (P2P_ROLE_GO == rtlpriv->mac80211.p2p) { 696 696 p2p_ps_offload->role = 1; 697 - p2p_ps_offload->allstasleep = -1; 697 + p2p_ps_offload->allstasleep = 0; 698 698 } else { 699 699 p2p_ps_offload->role = 0; 700 700 }
+7 -1
drivers/net/wireless/realtek/rtw88/bf.c
··· 124 124 void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif, 125 125 enum rtw_trx_desc_rate rate) 126 126 { 127 + u8 csi_rsc = CSI_RSC_FOLLOW_RX_PACKET_BW; 127 128 u32 psf_ctl = 0; 128 - u8 csi_rsc = 0x1; 129 + 130 + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) 131 + csi_rsc = CSI_RSC_PRIMARY_20M_BW; 129 132 130 133 psf_ctl = rtw_read32(rtwdev, REG_BBPSF_CTRL) | 131 134 BIT_WMAC_USE_NDPARATE | ··· 389 386 390 387 csi_cfg = rtw_read32(rtwdev, REG_BBPSF_CTRL) & ~BIT_MASK_CSI_RATE; 391 388 cur_rrsr = rtw_read16(rtwdev, REG_RRSR); 389 + 390 + if (rtwdev->chip->id == RTW_CHIP_TYPE_8822C) 391 + csi_cfg |= BIT_CSI_FORCE_RATE; 392 392 393 393 if (rssi >= 40) { 394 394 if (cur_rate != DESC_RATE54M) {
+7
drivers/net/wireless/realtek/rtw88/bf.h
··· 33 33 #define BIT_SHIFT_R_MU_RL 12 34 34 #define BIT_SHIFT_WMAC_TXMU_ACKPOLICY 4 35 35 #define BIT_SHIFT_CSI_RATE 24 36 + #define BIT_CSI_FORCE_RATE BIT(15) 36 37 37 38 #define BIT_MASK_R_MU_RL (R_MU_RL << BIT_SHIFT_R_MU_RL) 38 39 #define BIT_MASK_R_MU_TABLE_VALID 0x3f ··· 48 47 #define RTW_NDP_RX_STANDBY_TIME 0x70 49 48 #define RTW_SND_CTRL_REMOVE 0x98 50 49 #define RTW_SND_CTRL_SOUNDING 0x9B 50 + 51 + enum csi_rsc { 52 + CSI_RSC_PRIMARY_20M_BW = 0, 53 + CSI_RSC_FOLLOW_RX_PACKET_BW = 1, 54 + CSI_RSC_DUPLICATE_MODE = 2, 55 + }; 51 56 52 57 enum csi_seg_len { 53 58 HAL_CSI_SEG_4K = 0,
+2
drivers/net/wireless/realtek/rtw88/rtw8822bu.c
··· 79 79 .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* D-Link DWA-T185 rev. A1 */ 80 80 { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d1, 0xff, 0xff, 0xff), 81 81 .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U2-866DM */ 82 + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x03d0, 0xff, 0xff, 0xff), 83 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* BUFFALO WI-U3-866DHP */ 82 84 {}, 83 85 }; 84 86 MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table);
+2
drivers/net/wireless/realtek/rtw88/rtw8822cu.c
··· 21 21 .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, 22 22 { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff), 23 23 .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* Alpha - Alpha */ 24 + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3329, 0xff, 0xff, 0xff), 25 + .driver_info = (kernel_ulong_t)&(rtw8822c_hw_spec) }, /* D-Link AC13U rev. A1 */ 24 26 {}, 25 27 }; 26 28 MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);
+2 -1
drivers/net/wireless/realtek/rtw88/usb.c
··· 965 965 struct sk_buff *rx_skb; 966 966 int i; 967 967 968 - rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH, 0); 968 + rtwusb->rxwq = alloc_workqueue("rtw88_usb: rx wq", WQ_BH | WQ_UNBOUND, 969 + 0); 969 970 if (!rtwusb->rxwq) { 970 971 rtw_err(rtwdev, "failed to create RX work queue\n"); 971 972 return -ENOMEM;
+22
drivers/net/wireless/realtek/rtw89/Kconfig
··· 74 74 75 75 802.11ax PCIe wireless network (Wi-Fi 6) adapter 76 76 77 + config RTW89_8852AU 78 + tristate "Realtek 8852AU USB wireless network (Wi-Fi 6) adapter" 79 + depends on USB 80 + select RTW89_CORE 81 + select RTW89_USB 82 + select RTW89_8852A 83 + help 84 + Select this option will enable support for 8852AU chipset 85 + 86 + 802.11ax USB wireless network (Wi-Fi 6) adapter 87 + 77 88 config RTW89_8852BE 78 89 tristate "Realtek 8852BE PCI wireless network (Wi-Fi 6) adapter" 79 90 depends on PCI ··· 131 120 Select this option will enable support for 8852CE chipset 132 121 133 122 802.11ax PCIe wireless network (Wi-Fi 6E) adapter 123 + 124 + config RTW89_8852CU 125 + tristate "Realtek 8852CU USB wireless network (Wi-Fi 6E) adapter" 126 + depends on USB 127 + select RTW89_CORE 128 + select RTW89_USB 129 + select RTW89_8852C 130 + help 131 + Select this option will enable support for 8852CU chipset 132 + 133 + 802.11ax USB wireless network (Wi-Fi 6E) adapter 134 134 135 135 config RTW89_8922AE 136 136 tristate "Realtek 8922AE/8922AE-VS PCI wireless network (Wi-Fi 7) adapter"
+6
drivers/net/wireless/realtek/rtw89/Makefile
··· 43 43 obj-$(CONFIG_RTW89_8852AE) += rtw89_8852ae.o 44 44 rtw89_8852ae-objs := rtw8852ae.o 45 45 46 + obj-$(CONFIG_RTW89_8852AU) += rtw89_8852au.o 47 + rtw89_8852au-objs := rtw8852au.o 48 + 46 49 obj-$(CONFIG_RTW89_8852B_COMMON) += rtw89_8852b_common.o 47 50 rtw89_8852b_common-objs := rtw8852b_common.o 48 51 ··· 77 74 78 75 obj-$(CONFIG_RTW89_8852CE) += rtw89_8852ce.o 79 76 rtw89_8852ce-objs := rtw8852ce.o 77 + 78 + obj-$(CONFIG_RTW89_8852CU) += rtw89_8852cu.o 79 + rtw89_8852cu-objs := rtw8852cu.o 80 80 81 81 obj-$(CONFIG_RTW89_8922A) += rtw89_8922a.o 82 82 rtw89_8922a-objs := rtw8922a.o \
+90 -75
drivers/net/wireless/realtek/rtw89/cam.c
··· 236 236 if (ret) 237 237 rtw89_err(rtwdev, 238 238 "failed to update dctl cam del key: %d\n", ret); 239 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); 239 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 240 + RTW89_ROLE_INFO_CHANGE); 240 241 if (ret) 241 242 rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret); 242 243 } ··· 277 276 ret); 278 277 return ret; 279 278 } 280 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); 279 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 280 + RTW89_ROLE_INFO_CHANGE); 281 281 if (ret) { 282 282 rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n", 283 283 ret); ··· 762 760 763 761 int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, 764 762 struct rtw89_vif_link *rtwvif_link, 765 - struct rtw89_sta_link *rtwsta_link, u8 *cmd) 763 + struct rtw89_sta_link *rtwsta_link, 764 + struct rtw89_h2c_addr_cam_v0 *h2c) 766 765 { 767 766 struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link, 768 767 rtwsta_link); ··· 783 780 784 781 rcu_read_unlock(); 785 782 786 - FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx); 787 - FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset); 788 - FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len); 789 - FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid); 790 - FWCMD_SET_ADDR_BSSID_MASK(cmd, bss_mask); 791 - FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx); 792 - FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color); 793 - 794 - FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]); 795 - FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]); 796 - FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]); 797 - FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]); 798 - FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]); 799 - FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]); 783 + h2c->w12 = le32_encode_bits(bssid_cam->bssid_cam_idx, ADDR_CAM_W12_BSSID_IDX) | 784 + le32_encode_bits(bssid_cam->offset, ADDR_CAM_W12_BSSID_OFFSET) | 785 + le32_encode_bits(bssid_cam->len, ADDR_CAM_W12_BSSID_LEN); 786 + h2c->w13 = le32_encode_bits(bssid_cam->valid, ADDR_CAM_W13_BSSID_VALID) | 787 + le32_encode_bits(bss_mask, ADDR_CAM_W13_BSSID_MASK) | 788 + le32_encode_bits(bssid_cam->phy_idx, ADDR_CAM_W13_BSSID_BB_SEL) | 789 + le32_encode_bits(bss_color, ADDR_CAM_W13_BSSID_BSS_COLOR) | 790 + le32_encode_bits(bssid_cam->bssid[0], ADDR_CAM_W13_BSSID_BSSID0) | 791 + le32_encode_bits(bssid_cam->bssid[1], ADDR_CAM_W13_BSSID_BSSID1); 792 + h2c->w14 = le32_encode_bits(bssid_cam->bssid[2], ADDR_CAM_W14_BSSID_BSSID2) | 793 + le32_encode_bits(bssid_cam->bssid[3], ADDR_CAM_W14_BSSID_BSSID3) | 794 + le32_encode_bits(bssid_cam->bssid[4], ADDR_CAM_W14_BSSID_BSSID4) | 795 + le32_encode_bits(bssid_cam->bssid[5], ADDR_CAM_W14_BSSID_BSSID5); 800 796 801 797 return 0; 802 798 } ··· 815 813 struct rtw89_vif_link *rtwvif_link, 816 814 struct rtw89_sta_link *rtwsta_link, 817 815 const u8 *scan_mac_addr, 818 - u8 *cmd) 816 + struct rtw89_h2c_addr_cam_v0 *h2c) 819 817 { 820 818 struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link); 821 819 struct rtw89_addr_cam_entry *addr_cam = 822 820 rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link); 823 821 struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link); 822 + const struct rtw89_chip_info *chip = rtwdev->chip; 824 823 struct ieee80211_link_sta *link_sta; 825 824 const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr; 826 825 u8 sma_hash, tma_hash, addr_msk_start; 826 + u8 ver = chip->addrcam_ver; 827 827 u8 sma_start = 0; 828 828 u8 tma_start = 0; 829 829 const u8 *tma; 830 + u8 mac_id; 830 831 831 832 rcu_read_lock(); 832 833 ··· 850 845 sma_hash = rtw89_cam_addr_hash(sma_start, sma); 851 846 tma_hash = rtw89_cam_addr_hash(tma_start, tma); 852 847 853 - FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx); 854 - FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset); 855 - FWCMD_SET_ADDR_LEN(cmd, addr_cam->len); 848 + mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id; 856 849 857 - FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid); 858 - FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif_link->net_type); 859 - FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif_link->bcn_hit_cond); 860 - FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif_link->hit_rule); 861 - FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif_link->phy_idx); 862 - FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask); 863 - FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel); 864 - FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash); 865 - FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash); 850 + if (ver == 0) 851 + h2c->w1 = le32_encode_bits(addr_cam->addr_cam_idx, ADDR_CAM_W1_IDX) | 852 + le32_encode_bits(addr_cam->offset, ADDR_CAM_W1_OFFSET) | 853 + le32_encode_bits(addr_cam->len, ADDR_CAM_W1_LEN); 854 + else 855 + h2c->w1 = le32_encode_bits(addr_cam->addr_cam_idx, ADDR_CAM_W1_V1_IDX) | 856 + le32_encode_bits(addr_cam->offset, ADDR_CAM_W1_V1_OFFSET) | 857 + le32_encode_bits(addr_cam->len, ADDR_CAM_W1_V1_LEN); 866 858 867 - FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx); 859 + h2c->w2 = le32_encode_bits(addr_cam->valid, ADDR_CAM_W2_VALID) | 860 + le32_encode_bits(rtwvif_link->net_type, ADDR_CAM_W2_NET_TYPE) | 861 + le32_encode_bits(rtwvif_link->bcn_hit_cond, ADDR_CAM_W2_BCN_HIT_COND) | 862 + le32_encode_bits(rtwvif_link->hit_rule, ADDR_CAM_W2_HIT_RULE) | 863 + le32_encode_bits(rtwvif_link->phy_idx, ADDR_CAM_W2_BB_SEL) | 864 + le32_encode_bits(addr_cam->addr_mask, ADDR_CAM_W2_ADDR_MASK) | 865 + le32_encode_bits(addr_cam->mask_sel, ADDR_CAM_W2_MASK_SEL) | 866 + le32_encode_bits(sma_hash, ADDR_CAM_W2_SMA_HASH) | 867 + le32_encode_bits(tma_hash, ADDR_CAM_W2_TMA_HASH); 868 + h2c->w3 = le32_encode_bits(addr_cam->bssid_cam_idx, ADDR_CAM_W3_BSSID_CAM_IDX); 869 + h2c->w4 = le32_encode_bits(sma[0], ADDR_CAM_W4_SMA0) | 870 + le32_encode_bits(sma[1], ADDR_CAM_W4_SMA1) | 871 + le32_encode_bits(sma[2], ADDR_CAM_W4_SMA2) | 872 + le32_encode_bits(sma[3], ADDR_CAM_W4_SMA3); 873 + h2c->w5 = le32_encode_bits(sma[4], ADDR_CAM_W5_SMA4) | 874 + le32_encode_bits(sma[5], ADDR_CAM_W5_SMA5) | 875 + le32_encode_bits(tma[0], ADDR_CAM_W5_TMA0) | 876 + le32_encode_bits(tma[1], ADDR_CAM_W5_TMA1); 877 + h2c->w6 = le32_encode_bits(tma[2], ADDR_CAM_W6_TMA2) | 878 + le32_encode_bits(tma[3], ADDR_CAM_W6_TMA3) | 879 + le32_encode_bits(tma[4], ADDR_CAM_W6_TMA4) | 880 + le32_encode_bits(tma[5], ADDR_CAM_W6_TMA5); 881 + if (ver == 0) 882 + h2c->w8 = le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_PORT_INT) | 883 + le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_TSF_SYNC) | 884 + le32_encode_bits(rtwvif_link->trigger, ADDR_CAM_W8_TF_TRS) | 885 + le32_encode_bits(rtwvif_link->lsig_txop, ADDR_CAM_W8_LSIG_TXOP) | 886 + le32_encode_bits(rtwvif_link->tgt_ind, ADDR_CAM_W8_TGT_IND) | 887 + le32_encode_bits(rtwvif_link->frm_tgt_ind, ADDR_CAM_W8_FRM_TGT_IND) | 888 + le32_encode_bits(mac_id, ADDR_CAM_W8_MACID); 889 + else 890 + h2c->w8 = le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_V1_PORT_INT) | 891 + le32_encode_bits(rtwvif_link->port, ADDR_CAM_W8_V1_TSF_SYNC) | 892 + le32_encode_bits(rtwvif_link->trigger, ADDR_CAM_W8_V1_TF_TRS) | 893 + le32_encode_bits(rtwvif_link->lsig_txop, ADDR_CAM_W8_V1_LSIG_TXOP) | 894 + le32_encode_bits(mac_id, ADDR_CAM_W8_V1_MACID); 868 895 869 - FWCMD_SET_ADDR_SMA0(cmd, sma[0]); 870 - FWCMD_SET_ADDR_SMA1(cmd, sma[1]); 871 - FWCMD_SET_ADDR_SMA2(cmd, sma[2]); 872 - FWCMD_SET_ADDR_SMA3(cmd, sma[3]); 873 - FWCMD_SET_ADDR_SMA4(cmd, sma[4]); 874 - FWCMD_SET_ADDR_SMA5(cmd, sma[5]); 875 - 876 - FWCMD_SET_ADDR_TMA0(cmd, tma[0]); 877 - FWCMD_SET_ADDR_TMA1(cmd, tma[1]); 878 - FWCMD_SET_ADDR_TMA2(cmd, tma[2]); 879 - FWCMD_SET_ADDR_TMA3(cmd, tma[3]); 880 - FWCMD_SET_ADDR_TMA4(cmd, tma[4]); 881 - FWCMD_SET_ADDR_TMA5(cmd, tma[5]); 882 - 883 - FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif_link->port); 884 - FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif_link->port); 885 - FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif_link->trigger); 886 - FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif_link->lsig_txop); 887 - FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif_link->tgt_ind); 888 - FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif_link->frm_tgt_ind); 889 - FWCMD_SET_ADDR_MACID(cmd, rtwsta_link ? rtwsta_link->mac_id : 890 - rtwvif_link->mac_id); 891 896 if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA) 892 - FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff); 897 + h2c->w9 = le32_encode_bits(vif->cfg.aid & 0xfff, ADDR_CAM_W9_AID12); 893 898 else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) 894 - FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0); 895 - FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif_link->wowlan_pattern); 896 - FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif_link->wowlan_uc); 897 - FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif_link->wowlan_magic); 898 - FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi); 899 - FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode); 900 - FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]); 901 - FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]); 902 - FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]); 903 - FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]); 904 - FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]); 905 - FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]); 906 - FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]); 899 + h2c->w9 = le32_encode_bits(sta ? sta->aid & 0xfff : 0, ADDR_CAM_W9_AID12); 907 900 908 - FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff); 909 - FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]); 910 - FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]); 911 - FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]); 912 - FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]); 913 - FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]); 914 - FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]); 915 - FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]); 901 + h2c->w9 |= le32_encode_bits(rtwvif_link->wowlan_pattern, ADDR_CAM_W9_WOL_PATTERN) | 902 + le32_encode_bits(rtwvif_link->wowlan_uc, ADDR_CAM_W9_WOL_UC) | 903 + le32_encode_bits(rtwvif_link->wowlan_magic, ADDR_CAM_W9_WOL_MAGIC) | 904 + le32_encode_bits(addr_cam->wapi, ADDR_CAM_W9_WAPI) | 905 + le32_encode_bits(addr_cam->sec_ent_mode, ADDR_CAM_W9_SEC_ENT_MODE) | 906 + le32_encode_bits(addr_cam->sec_ent_keyid[0], ADDR_CAM_W9_SEC_ENT0_KEYID) | 907 + le32_encode_bits(addr_cam->sec_ent_keyid[1], ADDR_CAM_W9_SEC_ENT1_KEYID) | 908 + le32_encode_bits(addr_cam->sec_ent_keyid[2], ADDR_CAM_W9_SEC_ENT2_KEYID) | 909 + le32_encode_bits(addr_cam->sec_ent_keyid[3], ADDR_CAM_W9_SEC_ENT3_KEYID) | 910 + le32_encode_bits(addr_cam->sec_ent_keyid[4], ADDR_CAM_W9_SEC_ENT4_KEYID) | 911 + le32_encode_bits(addr_cam->sec_ent_keyid[5], ADDR_CAM_W9_SEC_ENT5_KEYID) | 912 + le32_encode_bits(addr_cam->sec_ent_keyid[6], ADDR_CAM_W9_SEC_ENT6_KEYID); 913 + h2c->w10 = le32_encode_bits(addr_cam->sec_cam_map[0] & 0xff, ADDR_CAM_W10_SEC_ENT_VALID) | 914 + le32_encode_bits(addr_cam->sec_ent[0], ADDR_CAM_W10_SEC_ENT0) | 915 + le32_encode_bits(addr_cam->sec_ent[1], ADDR_CAM_W10_SEC_ENT1) | 916 + le32_encode_bits(addr_cam->sec_ent[2], ADDR_CAM_W10_SEC_ENT2); 917 + h2c->w11 = le32_encode_bits(addr_cam->sec_ent[3], ADDR_CAM_W11_SEC_ENT3) | 918 + le32_encode_bits(addr_cam->sec_ent[4], ADDR_CAM_W11_SEC_ENT4) | 919 + le32_encode_bits(addr_cam->sec_ent[5], ADDR_CAM_W11_SEC_ENT5) | 920 + le32_encode_bits(addr_cam->sec_ent[6], ADDR_CAM_W11_SEC_ENT6); 916 921 917 922 rcu_read_unlock(); 918 923 }
+108 -342
drivers/net/wireless/realtek/rtw89/cam.h
··· 12 12 #define RTW89_BSSID_MATCH_ALL GENMASK(5, 0) 13 13 #define RTW89_BSSID_MATCH_5_BYTES GENMASK(4, 0) 14 14 15 - static inline void FWCMD_SET_ADDR_IDX(void *cmd, u32 value) 16 - { 17 - le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(7, 0)); 18 - } 19 - 20 - static inline void FWCMD_SET_ADDR_OFFSET(void *cmd, u32 value) 21 - { 22 - le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(15, 8)); 23 - } 24 - 25 - static inline void FWCMD_SET_ADDR_LEN(void *cmd, u32 value) 26 - { 27 - le32p_replace_bits((__le32 *)(cmd) + 1, value, GENMASK(23, 16)); 28 - } 29 - 30 - static inline void FWCMD_SET_ADDR_VALID(void *cmd, u32 value) 31 - { 32 - le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(0)); 33 - } 34 - 35 - static inline void FWCMD_SET_ADDR_NET_TYPE(void *cmd, u32 value) 36 - { 37 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(2, 1)); 38 - } 39 - 40 - static inline void FWCMD_SET_ADDR_BCN_HIT_COND(void *cmd, u32 value) 41 - { 42 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(4, 3)); 43 - } 44 - 45 - static inline void FWCMD_SET_ADDR_HIT_RULE(void *cmd, u32 value) 46 - { 47 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(6, 5)); 48 - } 49 - 50 - static inline void FWCMD_SET_ADDR_BB_SEL(void *cmd, u32 value) 51 - { 52 - le32p_replace_bits((__le32 *)(cmd) + 2, value, BIT(7)); 53 - } 54 - 55 - static inline void FWCMD_SET_ADDR_ADDR_MASK(void *cmd, u32 value) 56 - { 57 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(13, 8)); 58 - } 59 - 60 - static inline void FWCMD_SET_ADDR_MASK_SEL(void *cmd, u32 value) 61 - { 62 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(15, 14)); 63 - } 64 - 65 - static inline void FWCMD_SET_ADDR_SMA_HASH(void *cmd, u32 value) 66 - { 67 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(23, 16)); 68 - } 69 - 70 - static inline void FWCMD_SET_ADDR_TMA_HASH(void *cmd, u32 value) 71 - { 72 - le32p_replace_bits((__le32 *)(cmd) + 2, value, GENMASK(31, 24)); 73 - } 74 - 75 - static inline void FWCMD_SET_ADDR_BSSID_CAM_IDX(void *cmd, u32 value) 76 - { 77 - le32p_replace_bits((__le32 *)(cmd) + 3, value, GENMASK(5, 0)); 78 - } 79 - 80 - static inline void FWCMD_SET_ADDR_SMA0(void *cmd, u32 value) 81 - { 82 - le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(7, 0)); 83 - } 84 - 85 - static inline void FWCMD_SET_ADDR_SMA1(void *cmd, u32 value) 86 - { 87 - le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(15, 8)); 88 - } 89 - 90 - static inline void FWCMD_SET_ADDR_SMA2(void *cmd, u32 value) 91 - { 92 - le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(23, 16)); 93 - } 94 - 95 - static inline void FWCMD_SET_ADDR_SMA3(void *cmd, u32 value) 96 - { 97 - le32p_replace_bits((__le32 *)(cmd) + 4, value, GENMASK(31, 24)); 98 - } 99 - 100 - static inline void FWCMD_SET_ADDR_SMA4(void *cmd, u32 value) 101 - { 102 - le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(7, 0)); 103 - } 104 - 105 - static inline void FWCMD_SET_ADDR_SMA5(void *cmd, u32 value) 106 - { 107 - le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(15, 8)); 108 - } 109 - 110 - static inline void FWCMD_SET_ADDR_TMA0(void *cmd, u32 value) 111 - { 112 - le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(23, 16)); 113 - } 114 - 115 - static inline void FWCMD_SET_ADDR_TMA1(void *cmd, u32 value) 116 - { 117 - le32p_replace_bits((__le32 *)(cmd) + 5, value, GENMASK(31, 24)); 118 - } 119 - 120 - static inline void FWCMD_SET_ADDR_TMA2(void *cmd, u32 value) 121 - { 122 - le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(7, 0)); 123 - } 124 - 125 - static inline void FWCMD_SET_ADDR_TMA3(void *cmd, u32 value) 126 - { 127 - le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(15, 8)); 128 - } 129 - 130 - static inline void FWCMD_SET_ADDR_TMA4(void *cmd, u32 value) 131 - { 132 - le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(23, 16)); 133 - } 134 - 135 - static inline void FWCMD_SET_ADDR_TMA5(void *cmd, u32 value) 136 - { 137 - le32p_replace_bits((__le32 *)(cmd) + 6, value, GENMASK(31, 24)); 138 - } 139 - 140 - static inline void FWCMD_SET_ADDR_MACID(void *cmd, u32 value) 141 - { 142 - le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(7, 0)); 143 - } 144 - 145 - static inline void FWCMD_SET_ADDR_PORT_INT(void *cmd, u32 value) 146 - { 147 - le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(10, 8)); 148 - } 149 - 150 - static inline void FWCMD_SET_ADDR_TSF_SYNC(void *cmd, u32 value) 151 - { 152 - le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(13, 11)); 153 - } 154 - 155 - static inline void FWCMD_SET_ADDR_TF_TRS(void *cmd, u32 value) 156 - { 157 - le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(14)); 158 - } 159 - 160 - static inline void FWCMD_SET_ADDR_LSIG_TXOP(void *cmd, u32 value) 161 - { 162 - le32p_replace_bits((__le32 *)(cmd) + 8, value, BIT(15)); 163 - } 164 - 165 - static inline void FWCMD_SET_ADDR_TGT_IND(void *cmd, u32 value) 166 - { 167 - le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(26, 24)); 168 - } 169 - 170 - static inline void FWCMD_SET_ADDR_FRM_TGT_IND(void *cmd, u32 value) 171 - { 172 - le32p_replace_bits((__le32 *)(cmd) + 8, value, GENMASK(29, 27)); 173 - } 174 - 175 - static inline void FWCMD_SET_ADDR_AID12(void *cmd, u32 value) 176 - { 177 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 0)); 178 - } 179 - 180 - static inline void FWCMD_SET_ADDR_AID12_0(void *cmd, u32 value) 181 - { 182 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(7, 0)); 183 - } 184 - 185 - static inline void FWCMD_SET_ADDR_AID12_1(void *cmd, u32 value) 186 - { 187 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(11, 8)); 188 - } 189 - 190 - static inline void FWCMD_SET_ADDR_WOL_PATTERN(void *cmd, u32 value) 191 - { 192 - le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(12)); 193 - } 194 - 195 - static inline void FWCMD_SET_ADDR_WOL_UC(void *cmd, u32 value) 196 - { 197 - le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(13)); 198 - } 199 - 200 - static inline void FWCMD_SET_ADDR_WOL_MAGIC(void *cmd, u32 value) 201 - { 202 - le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(14)); 203 - } 204 - 205 - static inline void FWCMD_SET_ADDR_WAPI(void *cmd, u32 value) 206 - { 207 - le32p_replace_bits((__le32 *)(cmd) + 9, value, BIT(15)); 208 - } 209 - 210 - static inline void FWCMD_SET_ADDR_SEC_ENT_MODE(void *cmd, u32 value) 211 - { 212 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(17, 16)); 213 - } 214 - 215 - static inline void FWCMD_SET_ADDR_SEC_ENT0_KEYID(void *cmd, u32 value) 216 - { 217 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(19, 18)); 218 - } 219 - 220 - static inline void FWCMD_SET_ADDR_SEC_ENT1_KEYID(void *cmd, u32 value) 221 - { 222 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(21, 20)); 223 - } 224 - 225 - static inline void FWCMD_SET_ADDR_SEC_ENT2_KEYID(void *cmd, u32 value) 226 - { 227 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(23, 22)); 228 - } 229 - 230 - static inline void FWCMD_SET_ADDR_SEC_ENT3_KEYID(void *cmd, u32 value) 231 - { 232 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(25, 24)); 233 - } 234 - 235 - static inline void FWCMD_SET_ADDR_SEC_ENT4_KEYID(void *cmd, u32 value) 236 - { 237 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(27, 26)); 238 - } 239 - 240 - static inline void FWCMD_SET_ADDR_SEC_ENT5_KEYID(void *cmd, u32 value) 241 - { 242 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(29, 28)); 243 - } 244 - 245 - static inline void FWCMD_SET_ADDR_SEC_ENT6_KEYID(void *cmd, u32 value) 246 - { 247 - le32p_replace_bits((__le32 *)(cmd) + 9, value, GENMASK(31, 30)); 248 - } 249 - 250 - static inline void FWCMD_SET_ADDR_SEC_ENT_VALID(void *cmd, u32 value) 251 - { 252 - le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(7, 0)); 253 - } 254 - 255 - static inline void FWCMD_SET_ADDR_SEC_ENT0(void *cmd, u32 value) 256 - { 257 - le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(15, 8)); 258 - } 259 - 260 - static inline void FWCMD_SET_ADDR_SEC_ENT1(void *cmd, u32 value) 261 - { 262 - le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(23, 16)); 263 - } 264 - 265 - static inline void FWCMD_SET_ADDR_SEC_ENT2(void *cmd, u32 value) 266 - { 267 - le32p_replace_bits((__le32 *)(cmd) + 10, value, GENMASK(31, 24)); 268 - } 269 - 270 - static inline void FWCMD_SET_ADDR_SEC_ENT3(void *cmd, u32 value) 271 - { 272 - le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(7, 0)); 273 - } 274 - 275 - static inline void FWCMD_SET_ADDR_SEC_ENT4(void *cmd, u32 value) 276 - { 277 - le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(15, 8)); 278 - } 279 - 280 - static inline void FWCMD_SET_ADDR_SEC_ENT5(void *cmd, u32 value) 281 - { 282 - le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(23, 16)); 283 - } 284 - 285 - static inline void FWCMD_SET_ADDR_SEC_ENT6(void *cmd, u32 value) 286 - { 287 - le32p_replace_bits((__le32 *)(cmd) + 11, value, GENMASK(31, 24)); 288 - } 289 - 290 - static inline void FWCMD_SET_ADDR_BSSID_IDX(void *cmd, u32 value) 291 - { 292 - le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(7, 0)); 293 - } 294 - 295 - static inline void FWCMD_SET_ADDR_BSSID_OFFSET(void *cmd, u32 value) 296 - { 297 - le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(15, 8)); 298 - } 299 - 300 - static inline void FWCMD_SET_ADDR_BSSID_LEN(void *cmd, u32 value) 301 - { 302 - le32p_replace_bits((__le32 *)(cmd) + 12, value, GENMASK(23, 16)); 303 - } 304 - 305 - static inline void FWCMD_SET_ADDR_BSSID_VALID(void *cmd, u32 value) 306 - { 307 - le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(0)); 308 - } 309 - 310 - static inline void FWCMD_SET_ADDR_BSSID_BB_SEL(void *cmd, u32 value) 311 - { 312 - le32p_replace_bits((__le32 *)(cmd) + 13, value, BIT(1)); 313 - } 314 - 315 - static inline void FWCMD_SET_ADDR_BSSID_MASK(void *cmd, u32 value) 316 - { 317 - le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(7, 2)); 318 - } 319 - 320 - static inline void FWCMD_SET_ADDR_BSSID_BSS_COLOR(void *cmd, u32 value) 321 - { 322 - le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(13, 8)); 323 - } 324 - 325 - static inline void FWCMD_SET_ADDR_BSSID_BSSID0(void *cmd, u32 value) 326 - { 327 - le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(23, 16)); 328 - } 329 - 330 - static inline void FWCMD_SET_ADDR_BSSID_BSSID1(void *cmd, u32 value) 331 - { 332 - le32p_replace_bits((__le32 *)(cmd) + 13, value, GENMASK(31, 24)); 333 - } 334 - 335 - static inline void FWCMD_SET_ADDR_BSSID_BSSID2(void *cmd, u32 value) 336 - { 337 - le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(7, 0)); 338 - } 339 - 340 - static inline void FWCMD_SET_ADDR_BSSID_BSSID3(void *cmd, u32 value) 341 - { 342 - le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(15, 8)); 343 - } 344 - 345 - static inline void FWCMD_SET_ADDR_BSSID_BSSID4(void *cmd, u32 value) 346 - { 347 - le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(23, 16)); 348 - } 349 - 350 - static inline void FWCMD_SET_ADDR_BSSID_BSSID5(void *cmd, u32 value) 351 - { 352 - le32p_replace_bits((__le32 *)(cmd) + 14, value, GENMASK(31, 24)); 353 - } 15 + struct rtw89_h2c_addr_cam_v0 { 16 + __le32 w0; 17 + __le32 w1; 18 + __le32 w2; 19 + __le32 w3; 20 + __le32 w4; 21 + __le32 w5; 22 + __le32 w6; 23 + __le32 w7; 24 + __le32 w8; 25 + __le32 w9; 26 + __le32 w10; 27 + __le32 w11; 28 + __le32 w12; 29 + __le32 w13; 30 + __le32 w14; 31 + } __packed; 32 + 33 + struct rtw89_h2c_addr_cam { 34 + struct rtw89_h2c_addr_cam_v0 v0; 35 + __le32 w15; 36 + } __packed; 37 + 38 + #define ADDR_CAM_W1_IDX GENMASK(7, 0) 39 + #define ADDR_CAM_W1_OFFSET GENMASK(15, 8) 40 + #define ADDR_CAM_W1_LEN GENMASK(23, 16) 41 + #define ADDR_CAM_W1_V1_IDX GENMASK(9, 0) 42 + #define ADDR_CAM_W1_V1_OFFSET GENMASK(23, 16) 43 + #define ADDR_CAM_W1_V1_LEN GENMASK(31, 24) 44 + #define ADDR_CAM_W2_VALID BIT(0) 45 + #define ADDR_CAM_W2_NET_TYPE GENMASK(2, 1) 46 + #define ADDR_CAM_W2_BCN_HIT_COND GENMASK(4, 3) 47 + #define ADDR_CAM_W2_HIT_RULE GENMASK(6, 5) 48 + #define ADDR_CAM_W2_BB_SEL BIT(7) 49 + #define ADDR_CAM_W2_ADDR_MASK GENMASK(13, 8) 50 + #define ADDR_CAM_W2_MASK_SEL GENMASK(15, 14) 51 + #define ADDR_CAM_W2_SMA_HASH GENMASK(23, 16) 52 + #define ADDR_CAM_W2_TMA_HASH GENMASK(31, 24) 53 + #define ADDR_CAM_W3_BSSID_CAM_IDX GENMASK(5, 0) 54 + #define ADDR_CAM_W4_SMA0 GENMASK(7, 0) 55 + #define ADDR_CAM_W4_SMA1 GENMASK(15, 8) 56 + #define ADDR_CAM_W4_SMA2 GENMASK(23, 16) 57 + #define ADDR_CAM_W4_SMA3 GENMASK(31, 24) 58 + #define ADDR_CAM_W5_SMA4 GENMASK(7, 0) 59 + #define ADDR_CAM_W5_SMA5 GENMASK(15, 8) 60 + #define ADDR_CAM_W5_TMA0 GENMASK(23, 16) 61 + #define ADDR_CAM_W5_TMA1 GENMASK(31, 24) 62 + #define ADDR_CAM_W6_TMA2 GENMASK(7, 0) 63 + #define ADDR_CAM_W6_TMA3 GENMASK(15, 8) 64 + #define ADDR_CAM_W6_TMA4 GENMASK(23, 16) 65 + #define ADDR_CAM_W6_TMA5 GENMASK(31, 24) 66 + #define ADDR_CAM_W8_MACID GENMASK(7, 0) 67 + #define ADDR_CAM_W8_PORT_INT GENMASK(10, 8) 68 + #define ADDR_CAM_W8_TSF_SYNC GENMASK(13, 11) 69 + #define ADDR_CAM_W8_TF_TRS BIT(14) 70 + #define ADDR_CAM_W8_LSIG_TXOP BIT(15) 71 + #define ADDR_CAM_W8_TGT_IND GENMASK(26, 24) 72 + #define ADDR_CAM_W8_FRM_TGT_IND GENMASK(29, 27) 73 + #define ADDR_CAM_W8_V1_MACID GENMASK(9, 0) 74 + #define ADDR_CAM_W8_V1_PORT_INT GENMASK(18, 16) 75 + #define ADDR_CAM_W8_V1_TSF_SYNC GENMASK(21, 19) 76 + #define ADDR_CAM_W8_V1_TF_TRS BIT(22) 77 + #define ADDR_CAM_W8_V1_LSIG_TXOP BIT(23) 78 + #define ADDR_CAM_W8_V1_TB_RANGING BIT(24) 79 + #define ADDR_CAM_W8_V1_TB_SENSING BIT(25) 80 + #define ADDR_CAM_W8_V1_SENS_EN BIT(26) 81 + #define ADDR_CAM_W9_AID12 GENMASK(11, 0) 82 + #define ADDR_CAM_W9_AID12_0 GENMASK(7, 0) 83 + #define ADDR_CAM_W9_AID12_1 GENMASK(11, 8) 84 + #define ADDR_CAM_W9_WOL_PATTERN BIT(12) 85 + #define ADDR_CAM_W9_WOL_UC BIT(13) 86 + #define ADDR_CAM_W9_WOL_MAGIC BIT(14) 87 + #define ADDR_CAM_W9_WAPI BIT(15) 88 + #define ADDR_CAM_W9_SEC_ENT_MODE GENMASK(17, 16) 89 + #define ADDR_CAM_W9_SEC_ENT0_KEYID GENMASK(19, 18) 90 + #define ADDR_CAM_W9_SEC_ENT1_KEYID GENMASK(21, 20) 91 + #define ADDR_CAM_W9_SEC_ENT2_KEYID GENMASK(23, 22) 92 + #define ADDR_CAM_W9_SEC_ENT3_KEYID GENMASK(25, 24) 93 + #define ADDR_CAM_W9_SEC_ENT4_KEYID GENMASK(27, 26) 94 + #define ADDR_CAM_W9_SEC_ENT5_KEYID GENMASK(29, 28) 95 + #define ADDR_CAM_W9_SEC_ENT6_KEYID GENMASK(31, 30) 96 + #define ADDR_CAM_W10_SEC_ENT_VALID GENMASK(7, 0) 97 + #define ADDR_CAM_W10_SEC_ENT0 GENMASK(15, 8) 98 + #define ADDR_CAM_W10_SEC_ENT1 GENMASK(23, 16) 99 + #define ADDR_CAM_W10_SEC_ENT2 GENMASK(31, 24) 100 + #define ADDR_CAM_W11_SEC_ENT3 GENMASK(7, 0) 101 + #define ADDR_CAM_W11_SEC_ENT4 GENMASK(15, 8) 102 + #define ADDR_CAM_W11_SEC_ENT5 GENMASK(23, 16) 103 + #define ADDR_CAM_W11_SEC_ENT6 GENMASK(31, 24) 104 + #define ADDR_CAM_W12_BSSID_IDX GENMASK(7, 0) 105 + #define ADDR_CAM_W12_BSSID_OFFSET GENMASK(15, 8) 106 + #define ADDR_CAM_W12_BSSID_LEN GENMASK(23, 16) 107 + #define ADDR_CAM_W13_BSSID_VALID BIT(0) 108 + #define ADDR_CAM_W13_BSSID_BB_SEL BIT(1) 109 + #define ADDR_CAM_W13_BSSID_MASK GENMASK(7, 2) 110 + #define ADDR_CAM_W13_BSSID_BSS_COLOR GENMASK(13, 8) 111 + #define ADDR_CAM_W13_BSSID_BSSID0 GENMASK(23, 16) 112 + #define ADDR_CAM_W13_BSSID_BSSID1 GENMASK(31, 24) 113 + #define ADDR_CAM_W14_BSSID_BSSID2 GENMASK(7, 0) 114 + #define ADDR_CAM_W14_BSSID_BSSID3 GENMASK(15, 8) 115 + #define ADDR_CAM_W14_BSSID_BSSID4 GENMASK(23, 16) 116 + #define ADDR_CAM_W14_BSSID_BSSID5 GENMASK(31, 24) 117 + #define ADDR_CAM_W15_UPD_MODE GENMASK(2, 0) 354 118 355 119 struct rtw89_h2c_dctlinfo_ud_v1 { 356 120 __le32 c0; ··· 316 552 void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev, 317 553 struct rtw89_bssid_cam_entry *bssid_cam); 318 554 void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev, 319 - struct rtw89_vif_link *vif, 555 + struct rtw89_vif_link *rtwvif_link, 320 556 struct rtw89_sta_link *rtwsta_link, 321 - const u8 *scan_mac_addr, u8 *cmd); 557 + const u8 *scan_mac_addr, 558 + struct rtw89_h2c_addr_cam_v0 *h2c); 322 559 void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev, 323 560 struct rtw89_vif_link *rtwvif_link, 324 561 struct rtw89_sta_link *rtwsta_link, ··· 330 565 struct rtw89_h2c_dctlinfo_ud_v2 *h2c); 331 566 int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev, 332 567 struct rtw89_vif_link *rtwvif_link, 333 - struct rtw89_sta_link *rtwsta_link, u8 *cmd); 568 + struct rtw89_sta_link *rtwsta_link, 569 + struct rtw89_h2c_addr_cam_v0 *h2c); 334 570 int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev, 335 571 struct ieee80211_vif *vif, 336 572 struct ieee80211_sta *sta,
+180 -51
drivers/net/wireless/realtek/rtw89/core.c
··· 321 321 .n_bitrates = ARRAY_SIZE(rtw89_bitrates) - 4, 322 322 }; 323 323 324 + static const struct rtw89_hw_rate_def { 325 + enum rtw89_hw_rate ht; 326 + enum rtw89_hw_rate vht[RTW89_NSS_NUM]; 327 + } rtw89_hw_rate[RTW89_CHIP_GEN_NUM] = { 328 + [RTW89_CHIP_AX] = { 329 + .ht = RTW89_HW_RATE_MCS0, 330 + .vht = {RTW89_HW_RATE_VHT_NSS1_MCS0, 331 + RTW89_HW_RATE_VHT_NSS2_MCS0, 332 + RTW89_HW_RATE_VHT_NSS3_MCS0, 333 + RTW89_HW_RATE_VHT_NSS4_MCS0}, 334 + }, 335 + [RTW89_CHIP_BE] = { 336 + .ht = RTW89_HW_RATE_V1_MCS0, 337 + .vht = {RTW89_HW_RATE_V1_VHT_NSS1_MCS0, 338 + RTW89_HW_RATE_V1_VHT_NSS2_MCS0, 339 + RTW89_HW_RATE_V1_VHT_NSS3_MCS0, 340 + RTW89_HW_RATE_V1_VHT_NSS4_MCS0}, 341 + }, 342 + }; 343 + 324 344 static void __rtw89_traffic_stats_accu(struct rtw89_traffic_stats *stats, 325 345 struct sk_buff *skb, bool tx) 326 346 { ··· 470 450 __rtw89_core_set_chip_txpwr(rtwdev, chan, RTW89_PHY_1); 471 451 } 472 452 453 + static void rtw89_chip_rfk_channel_for_pure_mon_vif(struct rtw89_dev *rtwdev, 454 + enum rtw89_phy_idx phy_idx) 455 + { 456 + struct rtw89_vif *rtwvif = rtwdev->pure_monitor_mode_vif; 457 + struct rtw89_vif_link *rtwvif_link; 458 + 459 + if (!rtwvif) 460 + return; 461 + 462 + rtwvif_link = rtw89_vif_get_link_inst(rtwvif, phy_idx); 463 + if (!rtwvif_link) 464 + return; 465 + 466 + rtw89_chip_rfk_channel(rtwdev, rtwvif_link); 467 + } 468 + 473 469 static void __rtw89_set_channel(struct rtw89_dev *rtwdev, 474 470 const struct rtw89_chan *chan, 475 471 enum rtw89_mac_idx mac_idx, ··· 514 478 } 515 479 516 480 rtw89_set_entity_state(rtwdev, phy_idx, true); 481 + 482 + rtw89_chip_rfk_channel_for_pure_mon_vif(rtwdev, phy_idx); 517 483 } 518 484 519 485 int rtw89_set_channel(struct rtw89_dev *rtwdev) ··· 796 758 } 797 759 } 798 760 EXPORT_SYMBOL(rtw89_core_get_ch_dma_v1); 761 + 762 + u8 rtw89_core_get_ch_dma_v2(struct rtw89_dev *rtwdev, u8 qsel) 763 + { 764 + switch (qsel) { 765 + default: 766 + rtw89_warn(rtwdev, "Cannot map qsel to dma v2: %d\n", qsel); 767 + fallthrough; 768 + case RTW89_TX_QSEL_BE_0: 769 + case RTW89_TX_QSEL_VO_0: 770 + return RTW89_TXCH_ACH0; 771 + case RTW89_TX_QSEL_BK_0: 772 + case RTW89_TX_QSEL_VI_0: 773 + return RTW89_TXCH_ACH2; 774 + case RTW89_TX_QSEL_B0_MGMT: 775 + case RTW89_TX_QSEL_B0_HI: 776 + return RTW89_TXCH_CH8; 777 + } 778 + } 779 + EXPORT_SYMBOL(rtw89_core_get_ch_dma_v2); 799 780 800 781 static void 801 782 rtw89_core_tx_update_mgmt_info(struct rtw89_dev *rtwdev, ··· 1135 1078 rtw89_mac_notify_wake(rtwdev); 1136 1079 } 1137 1080 1081 + static void rtw89_core_tx_update_injection(struct rtw89_dev *rtwdev, 1082 + struct rtw89_core_tx_request *tx_req, 1083 + struct ieee80211_tx_info *info) 1084 + { 1085 + const struct rtw89_hw_rate_def *hw_rate = &rtw89_hw_rate[rtwdev->chip->chip_gen]; 1086 + enum mac80211_rate_control_flags flags = info->control.rates[0].flags; 1087 + struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; 1088 + const struct rtw89_chan *chan; 1089 + u8 idx = info->control.rates[0].idx; 1090 + u8 nss, mcs; 1091 + 1092 + desc_info->use_rate = true; 1093 + desc_info->dis_data_fb = true; 1094 + 1095 + if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH) 1096 + desc_info->data_bw = 3; 1097 + else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH) 1098 + desc_info->data_bw = 2; 1099 + else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1100 + desc_info->data_bw = 1; 1101 + 1102 + if (flags & IEEE80211_TX_RC_SHORT_GI) 1103 + desc_info->gi_ltf = 1; 1104 + 1105 + if (flags & IEEE80211_TX_RC_VHT_MCS) { 1106 + nss = umin(idx >> 4, ARRAY_SIZE(hw_rate->vht) - 1); 1107 + mcs = idx & 0xf; 1108 + desc_info->data_rate = hw_rate->vht[nss] + mcs; 1109 + } else if (flags & IEEE80211_TX_RC_MCS) { 1110 + desc_info->data_rate = hw_rate->ht + idx; 1111 + } else { 1112 + chan = rtw89_chan_get(rtwdev, tx_req->rtwvif_link->chanctx_idx); 1113 + 1114 + desc_info->data_rate = idx + (chan->band_type == RTW89_BAND_2G ? 1115 + RTW89_HW_RATE_CCK1 : RTW89_HW_RATE_OFDM6); 1116 + } 1117 + } 1118 + 1138 1119 static void 1139 1120 rtw89_core_tx_update_desc_info(struct rtw89_dev *rtwdev, 1140 1121 struct rtw89_core_tx_request *tx_req) ··· 1182 1087 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1183 1088 struct ieee80211_hdr *hdr = (void *)skb->data; 1184 1089 struct rtw89_addr_cam_entry *addr_cam; 1185 - enum rtw89_core_tx_type tx_type; 1186 1090 enum btc_pkt_type pkt_type; 1187 1091 bool upd_wlan_hdr = false; 1188 1092 bool is_bmc; 1189 1093 u16 seq; 1094 + 1095 + desc_info->pkt_size = skb->len; 1096 + 1097 + if (unlikely(tx_req->tx_type == RTW89_CORE_TX_TYPE_FWCMD)) { 1098 + rtw89_core_tx_update_h2c_info(rtwdev, tx_req); 1099 + return; 1100 + } 1101 + 1102 + tx_req->tx_type = rtw89_core_get_tx_type(rtwdev, skb); 1190 1103 1191 1104 if (tx_req->sta) 1192 1105 desc_info->mlo = tx_req->sta->mlo; ··· 1202 1099 desc_info->mlo = ieee80211_vif_is_mld(tx_req->vif); 1203 1100 1204 1101 seq = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; 1205 - if (tx_req->tx_type != RTW89_CORE_TX_TYPE_FWCMD) { 1206 - tx_type = rtw89_core_get_tx_type(rtwdev, skb); 1207 - tx_req->tx_type = tx_type; 1102 + addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link, 1103 + tx_req->rtwsta_link); 1104 + if (addr_cam->valid && desc_info->mlo) 1105 + upd_wlan_hdr = true; 1208 1106 1209 - addr_cam = rtw89_get_addr_cam_of(tx_req->rtwvif_link, 1210 - tx_req->rtwsta_link); 1211 - if (addr_cam->valid && desc_info->mlo) 1212 - upd_wlan_hdr = true; 1213 - } 1107 + if (rtw89_is_tx_rpt_skb(rtwdev, tx_req->skb)) 1108 + rtw89_tx_rpt_init(rtwdev, tx_req); 1109 + 1214 1110 is_bmc = (is_broadcast_ether_addr(hdr->addr1) || 1215 1111 is_multicast_ether_addr(hdr->addr1)); 1216 1112 1217 1113 desc_info->seq = seq; 1218 - desc_info->pkt_size = skb->len; 1219 1114 desc_info->is_bmc = is_bmc; 1220 1115 desc_info->wd_page = true; 1221 1116 desc_info->hiq = info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM; ··· 1230 1129 rtw89_core_tx_update_ampdu_info(rtwdev, tx_req, pkt_type); 1231 1130 rtw89_core_tx_update_llc_hdr(rtwdev, desc_info, skb); 1232 1131 break; 1233 - case RTW89_CORE_TX_TYPE_FWCMD: 1234 - rtw89_core_tx_update_h2c_info(rtwdev, tx_req); 1132 + default: 1235 1133 break; 1236 1134 } 1135 + 1136 + if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) 1137 + rtw89_core_tx_update_injection(rtwdev, tx_req, info); 1237 1138 } 1238 1139 1239 1140 static void rtw89_tx_wait_work(struct wiphy *wiphy, struct wiphy_work *work) ··· 1342 1239 tx_req.rtwvif_link = rtwvif_link; 1343 1240 tx_req.rtwsta_link = rtwsta_link; 1344 1241 tx_req.desc_info.sw_mld = sw_mld; 1242 + rcu_assign_pointer(skb_data->wait, wait); 1345 1243 1346 1244 rtw89_traffic_stats_accu(rtwdev, rtwvif, skb, true, true); 1347 1245 rtw89_wow_parse_akm(rtwdev, skb); 1348 1246 rtw89_core_tx_update_desc_info(rtwdev, &tx_req); 1349 1247 rtw89_core_tx_wake(rtwdev, &tx_req); 1350 - 1351 - rcu_assign_pointer(skb_data->wait, wait); 1352 1248 1353 1249 ret = rtw89_hci_tx_write(rtwdev, &tx_req); 1354 1250 if (ret) { ··· 1464 1362 static __le32 rtw89_build_txwd_body7_v1(struct rtw89_tx_desc_info *desc_info) 1465 1363 { 1466 1364 u32 dword = FIELD_PREP(RTW89_TXWD_BODY7_USE_RATE_V1, desc_info->use_rate) | 1365 + FIELD_PREP(RTW89_TXWD_BODY7_DATA_BW, desc_info->data_bw) | 1366 + FIELD_PREP(RTW89_TXWD_BODY7_GI_LTF, desc_info->gi_ltf) | 1467 1367 FIELD_PREP(RTW89_TXWD_BODY7_DATA_RATE, desc_info->data_rate); 1468 1368 1469 1369 return cpu_to_le32(dword); ··· 1474 1370 static __le32 rtw89_build_txwd_info0(struct rtw89_tx_desc_info *desc_info) 1475 1371 { 1476 1372 u32 dword = FIELD_PREP(RTW89_TXWD_INFO0_USE_RATE, desc_info->use_rate) | 1373 + FIELD_PREP(RTW89_TXWD_INFO0_DATA_BW, desc_info->data_bw) | 1374 + FIELD_PREP(RTW89_TXWD_INFO0_GI_LTF, desc_info->gi_ltf) | 1477 1375 FIELD_PREP(RTW89_TXWD_INFO0_DATA_RATE, desc_info->data_rate) | 1478 1376 FIELD_PREP(RTW89_TXWD_INFO0_DATA_STBC, desc_info->stbc) | 1479 1377 FIELD_PREP(RTW89_TXWD_INFO0_DATA_LDPC, desc_info->ldpc) | ··· 1502 1396 u32 dword = FIELD_PREP(RTW89_TXWD_INFO1_MAX_AGGNUM, desc_info->ampdu_num) | 1503 1397 FIELD_PREP(RTW89_TXWD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | 1504 1398 FIELD_PREP(RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE, 1505 - desc_info->data_retry_lowest_rate); 1399 + desc_info->data_retry_lowest_rate) | 1400 + FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL, 1401 + desc_info->tx_cnt_lmt_en) | 1402 + FIELD_PREP(RTW89_TXWD_INFO1_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt); 1506 1403 1507 1404 return cpu_to_le32(dword); 1508 1405 } ··· 1529 1420 return cpu_to_le32(dword); 1530 1421 } 1531 1422 1423 + static __le32 rtw89_build_txwd_info3(struct rtw89_tx_desc_info *desc_info) 1424 + { 1425 + u32 dword = FIELD_PREP(RTW89_TXWD_INFO3_SPE_RPT, desc_info->report); 1426 + 1427 + return cpu_to_le32(dword); 1428 + } 1429 + 1532 1430 static __le32 rtw89_build_txwd_info4(struct rtw89_tx_desc_info *desc_info) 1533 1431 { 1534 1432 bool rts_en = !desc_info->is_bmc; 1535 1433 u32 dword = FIELD_PREP(RTW89_TXWD_INFO4_RTS_EN, rts_en) | 1536 - FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1); 1434 + FIELD_PREP(RTW89_TXWD_INFO4_HW_RTS_EN, 1) | 1435 + FIELD_PREP(RTW89_TXWD_INFO4_SW_DEFINE, desc_info->sn); 1537 1436 1538 1437 return cpu_to_le32(dword); 1539 1438 } ··· 1564 1447 txwd_info->dword0 = rtw89_build_txwd_info0(desc_info); 1565 1448 txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); 1566 1449 txwd_info->dword2 = rtw89_build_txwd_info2(desc_info); 1450 + txwd_info->dword3 = rtw89_build_txwd_info3(desc_info); 1567 1451 txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); 1568 1452 1569 1453 } ··· 1594 1476 txwd_info->dword0 = rtw89_build_txwd_info0_v1(desc_info); 1595 1477 txwd_info->dword1 = rtw89_build_txwd_info1(desc_info); 1596 1478 txwd_info->dword2 = rtw89_build_txwd_info2_v1(desc_info); 1479 + txwd_info->dword3 = rtw89_build_txwd_info3(desc_info); 1597 1480 txwd_info->dword4 = rtw89_build_txwd_info4(desc_info); 1598 1481 } 1599 1482 EXPORT_SYMBOL(rtw89_core_fill_txdesc_v1); ··· 1668 1549 static __le32 rtw89_build_txwd_body7_v2(struct rtw89_tx_desc_info *desc_info) 1669 1550 { 1670 1551 u32 dword = FIELD_PREP(BE_TXD_BODY7_USERATE_SEL, desc_info->use_rate) | 1552 + FIELD_PREP(BE_TXD_BODY7_DATA_BW, desc_info->data_bw) | 1553 + FIELD_PREP(BE_TXD_BODY7_GI_LTF, desc_info->gi_ltf) | 1671 1554 FIELD_PREP(BE_TXD_BODY7_DATA_ER, desc_info->er_cap) | 1672 1555 FIELD_PREP(BE_TXD_BODY7_DATA_BW_ER, 0) | 1673 1556 FIELD_PREP(BE_TXD_BODY7_DATARATE, desc_info->data_rate); ··· 1682 1561 u32 dword = FIELD_PREP(BE_TXD_INFO0_DATA_STBC, desc_info->stbc) | 1683 1562 FIELD_PREP(BE_TXD_INFO0_DATA_LDPC, desc_info->ldpc) | 1684 1563 FIELD_PREP(BE_TXD_INFO0_DISDATAFB, desc_info->dis_data_fb) | 1685 - FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port); 1564 + FIELD_PREP(BE_TXD_INFO0_MULTIPORT_ID, desc_info->port) | 1565 + FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT_SEL, 1566 + desc_info->tx_cnt_lmt_en) | 1567 + FIELD_PREP(BE_TXD_INFO0_DATA_TXCNT_LMT, desc_info->tx_cnt_lmt); 1686 1568 1687 1569 return cpu_to_le32(dword); 1688 1570 } ··· 1695 1571 u32 dword = FIELD_PREP(BE_TXD_INFO1_MAX_AGG_NUM, desc_info->ampdu_num) | 1696 1572 FIELD_PREP(BE_TXD_INFO1_A_CTRL_BSR, desc_info->a_ctrl_bsr) | 1697 1573 FIELD_PREP(BE_TXD_INFO1_DATA_RTY_LOWEST_RATE, 1698 - desc_info->data_retry_lowest_rate); 1574 + desc_info->data_retry_lowest_rate) | 1575 + FIELD_PREP(BE_TXD_INFO1_SW_DEFINE, desc_info->sn); 1699 1576 1700 1577 return cpu_to_le32(dword); 1701 1578 } ··· 1705 1580 { 1706 1581 u32 dword = FIELD_PREP(BE_TXD_INFO2_AMPDU_DENSITY, desc_info->ampdu_density) | 1707 1582 FIELD_PREP(BE_TXD_INFO2_FORCE_KEY_EN, desc_info->sec_en) | 1708 - FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx); 1583 + FIELD_PREP(BE_TXD_INFO2_SEC_CAM_IDX, desc_info->sec_cam_idx) | 1584 + FIELD_PREP(BE_TXD_INFO2_SPE_RPT_V1, desc_info->report); 1709 1585 1710 1586 return cpu_to_le32(dword); 1711 1587 } ··· 1834 1708 /* For WiFi 7 chips, RXWD.mac_id of PPDU status is not set 1835 1709 * by hardware, so update mac_id by rxinfo_user[].mac_id. 1836 1710 */ 1837 - if (chip_gen == RTW89_CHIP_BE) 1711 + if (chip->chip_id == RTL8922A) 1838 1712 phy_ppdu->mac_id = 1839 1713 le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID); 1714 + else if (chip->chip_id == RTL8922D) 1715 + phy_ppdu->mac_id = 1716 + le32_get_bits(user->w0, RTW89_RXINFO_USER_MACID_V1); 1717 + 1840 1718 phy_ppdu->has_data = 1841 1719 le32_get_bits(user->w0, RTW89_RXINFO_USER_DATA); 1842 1720 phy_ppdu->has_bcn = ··· 3762 3632 struct ieee80211_sta *sta) 3763 3633 { 3764 3634 struct rtw89_sta *rtwsta = sta_to_rtwsta(sta); 3765 - struct sk_buff *skb, *tmp; 3635 + struct sk_buff *skb; 3766 3636 3767 - skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { 3768 - skb_unlink(skb, &rtwsta->roc_queue); 3637 + while ((skb = skb_dequeue(&rtwsta->roc_queue))) 3769 3638 dev_kfree_skb_any(skb); 3770 - } 3771 3639 } 3772 3640 3773 3641 static void rtw89_core_stop_tx_ba_session(struct rtw89_dev *rtwdev, ··· 4009 3881 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 4010 3882 struct rtw89_vif_link *target = data; 4011 3883 struct rtw89_vif_link *rtwvif_link; 4012 - struct sk_buff *skb, *tmp; 4013 3884 unsigned int link_id; 3885 + struct sk_buff *skb; 4014 3886 int qsel, ret; 4015 3887 4016 3888 rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) ··· 4023 3895 if (skb_queue_len(&rtwsta->roc_queue) == 0) 4024 3896 return; 4025 3897 4026 - skb_queue_walk_safe(&rtwsta->roc_queue, skb, tmp) { 4027 - skb_unlink(skb, &rtwsta->roc_queue); 4028 - 3898 + while ((skb = skb_dequeue(&rtwsta->roc_queue))) { 4029 3899 ret = rtw89_core_tx_write(rtwdev, vif, sta, skb, &qsel); 4030 3900 if (ret) { 4031 3901 rtw89_warn(rtwdev, "pending tx failed with %d\n", ret); ··· 4173 4047 4174 4048 void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) 4175 4049 { 4176 - const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 4177 4050 struct ieee80211_hw *hw = rtwdev->hw; 4178 4051 struct rtw89_roc *roc = &rtwvif->roc; 4179 4052 struct rtw89_vif_link *rtwvif_link; 4180 4053 struct rtw89_vif *tmp_vif; 4181 - u32 reg; 4182 4054 int ret; 4183 4055 4184 4056 lockdep_assert_wiphy(hw->wiphy); ··· 4193 4069 return; 4194 4070 } 4195 4071 4196 - reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); 4197 - rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr); 4072 + rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr); 4198 4073 4199 4074 roc->state = RTW89_ROC_IDLE; 4200 4075 rtw89_config_roc_chandef(rtwdev, rtwvif_link, NULL); ··· 4824 4701 } 4825 4702 4826 4703 /* update cam aid mac_id net_type */ 4827 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); 4704 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 4705 + RTW89_ROLE_CON_DISCONN); 4828 4706 if (ret) { 4829 4707 rtw89_warn(rtwdev, "failed to send h2c cam\n"); 4830 4708 return ret; ··· 4899 4775 } 4900 4776 4901 4777 /* update cam aid mac_id net_type */ 4902 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); 4778 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 4779 + RTW89_ROLE_CON_DISCONN); 4903 4780 if (ret) { 4904 4781 rtw89_warn(rtwdev, "failed to send h2c cam\n"); 4905 4782 return ret; ··· 5618 5493 5619 5494 int rtw89_core_start(struct rtw89_dev *rtwdev) 5620 5495 { 5496 + bool no_bbmcu = !rtwdev->chip->bbmcu_nr; 5621 5497 int ret; 5622 5498 5499 + ret = rtw89_mac_preinit(rtwdev); 5500 + if (ret) { 5501 + rtw89_err(rtwdev, "mac preinit fail, ret: %d\n", ret); 5502 + return ret; 5503 + } 5504 + 5505 + if (no_bbmcu) 5506 + rtw89_chip_bb_preinit(rtwdev); 5507 + 5623 5508 rtw89_phy_init_bb_afe(rtwdev); 5509 + 5510 + /* above do preinit before downloading firmware */ 5624 5511 5625 5512 ret = rtw89_mac_init(rtwdev); 5626 5513 if (ret) { ··· 5679 5542 rtw89_fw_h2c_fw_log(rtwdev, rtwdev->fw.log.enable); 5680 5543 rtw89_fw_h2c_init_ba_cam(rtwdev); 5681 5544 rtw89_tas_fw_timer_enable(rtwdev, true); 5545 + rtwdev->ps_hang_cnt = 0; 5682 5546 5683 5547 return 0; 5684 5548 } ··· 5967 5829 wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work); 5968 5830 INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work); 5969 5831 5832 + spin_lock_init(&rtwdev->tx_rpt.skb_lock); 5970 5833 skb_queue_head_init(&rtwdev->c2h_queue); 5971 5834 rtw89_core_ppdu_sts_init(rtwdev); 5972 5835 rtw89_traffic_stats_init(rtwdev, &rtwdev->stats); ··· 6032 5893 rtw89_phy_config_edcca(rtwdev, bb, true); 6033 5894 rtw89_tas_scan(rtwdev, true); 6034 5895 6035 - rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr); 5896 + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr, 5897 + RTW89_ROLE_INFO_CHANGE); 6036 5898 } 6037 5899 6038 5900 void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, ··· 6053 5913 6054 5914 rcu_read_unlock(); 6055 5915 6056 - rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); 5916 + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, 5917 + RTW89_ROLE_INFO_CHANGE); 6057 5918 6058 5919 rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false); 6059 5920 rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx); ··· 6155 6014 struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); 6156 6015 u16 usable_links = ieee80211_vif_usable_links(vif); 6157 6016 u16 active_links = vif->active_links; 6158 - struct rtw89_vif_link *target, *cur; 6017 + struct rtw89_vif_link *target; 6159 6018 int ret; 6160 6019 6161 6020 lockdep_assert_wiphy(rtwdev->hw->wiphy); ··· 6181 6040 ieee80211_stop_queues(rtwdev->hw); 6182 6041 flush_work(&rtwdev->txq_work); 6183 6042 6184 - cur = rtw89_get_designated_link(rtwvif); 6185 - 6186 - ret = ieee80211_set_active_links(vif, active_links | BIT(link_id)); 6043 + ret = ieee80211_set_active_links(vif, BIT(link_id)); 6187 6044 if (ret) { 6188 - rtw89_err(rtwdev, "%s: failed to activate link id %u\n", 6045 + rtw89_err(rtwdev, "%s: failed to work on link id %u\n", 6189 6046 __func__, link_id); 6190 6047 goto wake_queue; 6191 6048 } ··· 6197 6058 ret = -EFAULT; 6198 6059 goto wake_queue; 6199 6060 } 6200 - 6201 - if (likely(cur)) 6202 - rtw89_fw_h2c_mlo_link_cfg(rtwdev, cur, false); 6203 - 6204 - rtw89_fw_h2c_mlo_link_cfg(rtwdev, target, true); 6205 - 6206 - ret = ieee80211_set_active_links(vif, BIT(link_id)); 6207 - if (ret) 6208 - rtw89_err(rtwdev, "%s: failed to inactivate links 0x%x\n", 6209 - __func__, active_links); 6210 6061 6211 6062 rtw89_chip_rfk_channel(rtwdev, target); 6212 6063
+88 -16
drivers/net/wireless/realtek/rtw89/core.h
··· 15 15 16 16 struct rtw89_dev; 17 17 struct rtw89_pci_info; 18 + struct rtw89_usb_info; 18 19 struct rtw89_mac_gen_def; 19 20 struct rtw89_phy_gen_def; 20 21 struct rtw89_fw_blacklist; ··· 39 38 #define RFREG_MASK 0xfffff 40 39 #define INV_RF_DATA 0xffffffff 41 40 #define BYPASS_CR_DATA 0xbabecafe 41 + #define RTW89_R32_EA 0xEAEAEAEA 42 + #define RTW89_R32_DEAD 0xDEADBEEF 42 43 43 44 #define RTW89_TRACK_WORK_PERIOD round_jiffies_relative(HZ * 2) 44 45 #define RTW89_TRACK_PS_WORK_PERIOD msecs_to_jiffies(100) 45 46 #define RTW89_FORBID_BA_TIMER round_jiffies_relative(HZ * 4) 47 + #define RTW89_PS_HANG_MAX_CNT 3 46 48 #define CFO_TRACK_MAX_USER 64 47 49 #define MAX_RSSI 110 48 50 #define RSSI_FACTOR 1 ··· 155 151 RTL8852C, 156 152 RTL8851B, 157 153 RTL8922A, 154 + RTL8922D, 158 155 }; 159 156 160 157 enum rtw89_chip_gen { ··· 1172 1167 u8 ampdu_density; 1173 1168 u8 ampdu_num; 1174 1169 bool sec_en; 1170 + bool report; 1171 + bool tx_cnt_lmt_en; 1172 + u8 sn: 4; 1173 + u8 tx_cnt_lmt: 6; 1175 1174 u8 addr_info_nr; 1176 1175 u8 sec_keyid; 1177 1176 u8 sec_type; ··· 1183 1174 u8 sec_seq[6]; 1184 1175 u16 data_rate; 1185 1176 u16 data_retry_lowest_rate; 1177 + u8 data_bw; 1178 + u8 gi_ltf; 1186 1179 bool fw_dl; 1187 1180 u16 seq; 1188 1181 bool a_ctrl_bsr; ··· 3385 3374 u8 cr_tbl_sel:1; 3386 3375 u8 fix_giltf_en:1; 3387 3376 u8 fix_giltf:3; 3388 - u8 rsvd2:1; 3377 + u8 partial_bw_er:1; 3389 3378 u8 csi_mcs_ss_idx; 3390 3379 u8 csi_mode:2; 3391 3380 u8 csi_gi_ltf:3; 3392 3381 u8 csi_bw:3; 3382 + /* after v1 */ 3383 + u8 is_noisy:1; 3384 + u8 psra_en:1; 3385 + u8 rsvd0:1; 3386 + u8 macid_msb:2; 3387 + u8 band:2; /* enum rtw89_band */ 3388 + u8 is_new_dbgreg:1; 3393 3389 }; 3394 3390 3395 3391 #define RTW89_PPDU_MAC_INFO_USR_SIZE 4 ··· 3525 3507 bool enable; 3526 3508 }; 3527 3509 3510 + #define RTW89_TX_DONE 0x0 3511 + #define RTW89_TX_RETRY_LIMIT 0x1 3512 + #define RTW89_TX_LIFE_TIME 0x2 3513 + #define RTW89_TX_MACID_DROP 0x3 3514 + 3515 + #define RTW89_MAX_TX_RPTS 16 3516 + #define RTW89_MAX_TX_RPTS_MASK (RTW89_MAX_TX_RPTS - 1) 3517 + struct rtw89_tx_rpt { 3518 + struct sk_buff *skbs[RTW89_MAX_TX_RPTS]; 3519 + /* protect skbs array access/modification */ 3520 + spinlock_t skb_lock; 3521 + atomic_t sn; 3522 + }; 3523 + 3528 3524 #define RTW89_TX_WAIT_WORK_TIMEOUT msecs_to_jiffies(500) 3529 3525 struct rtw89_tx_wait_info { 3530 3526 struct rcu_head rcu_head; ··· 3550 3518 3551 3519 struct rtw89_tx_skb_data { 3552 3520 struct rtw89_tx_wait_info __rcu *wait; 3521 + u8 tx_rpt_sn; 3522 + u8 tx_pkt_cnt_lmt; 3553 3523 u8 hci_priv[]; 3554 3524 }; 3555 3525 ··· 3686 3652 void (*write16)(struct rtw89_dev *rtwdev, u32 addr, u16 data); 3687 3653 void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data); 3688 3654 3655 + u32 (*read32_pci_cfg)(struct rtw89_dev *rtwdev, u32 addr); 3656 + 3689 3657 int (*mac_pre_init)(struct rtw89_dev *rtwdev); 3690 3658 int (*mac_pre_deinit)(struct rtw89_dev *rtwdev); 3691 3659 int (*mac_post_init)(struct rtw89_dev *rtwdev); ··· 3723 3687 u32 rpwm_addr; 3724 3688 u32 cpwm_addr; 3725 3689 bool paused; 3690 + bool tx_rpt_enabled; 3726 3691 }; 3727 3692 3728 3693 struct rtw89_chip_ops { ··· 3800 3763 void (*fill_txdesc_fwcmd)(struct rtw89_dev *rtwdev, 3801 3764 struct rtw89_tx_desc_info *desc_info, 3802 3765 void *txdesc); 3803 - u8 (*get_ch_dma)(struct rtw89_dev *rtwdev, u8 qsel); 3766 + u8 (*get_ch_dma[RTW89_HCI_TYPE_NUM])(struct rtw89_dev *rtwdev, u8 qsel); 3804 3767 int (*cfg_ctrl_path)(struct rtw89_dev *rtwdev, bool wl); 3805 3768 int (*mac_cfg_gnt)(struct rtw89_dev *rtwdev, 3806 3769 const struct rtw89_mac_ax_coex_gnt *gnt_cfg); ··· 4459 4422 u8 bacam_num; 4460 4423 u8 bacam_dynamic_num; 4461 4424 enum rtw89_bacam_ver bacam_ver; 4425 + u8 addrcam_ver; 4462 4426 u8 ppdu_max_usr; 4463 4427 4464 4428 u8 sec_ctrl_efuse_size; ··· 4551 4513 4552 4514 union rtw89_bus_info { 4553 4515 const struct rtw89_pci_info *pci; 4516 + const struct rtw89_usb_info *usb; 4554 4517 }; 4555 4518 4556 4519 struct rtw89_driver_info { ··· 4679 4640 RTW89_FW_FEATURE_RFK_NTFY_MCC_V0, 4680 4641 RTW89_FW_FEATURE_LPS_DACK_BY_C2H_REG, 4681 4642 RTW89_FW_FEATURE_BEACON_TRACKING, 4643 + RTW89_FW_FEATURE_ADDR_CAM_V0, 4682 4644 }; 4683 4645 4684 4646 struct rtw89_fw_suit { ··· 4740 4700 struct rtw89_phy_rfk_log_fmt *rfk_log_fmt; 4741 4701 const struct rtw89_regd_data *regd; 4742 4702 const struct rtw89_fw_element_hdr *afe; 4703 + const struct rtw89_fw_element_hdr *diag_mac; 4743 4704 }; 4744 4705 4745 4706 enum rtw89_fw_mss_dev_type { ··· 5490 5449 struct rtw89_regulatory_info { 5491 5450 struct rtw89_regd_ctrl ctrl; 5492 5451 const struct rtw89_regd *regd; 5452 + bool programmed; 5453 + 5493 5454 enum rtw89_reg_6ghz_power reg_6ghz_power; 5494 5455 struct rtw89_reg_6ghz_tpe reg_6ghz_tpe; 5495 5456 bool txpwr_uk_follow_etsi; ··· 5976 5933 5977 5934 enum rtw89_mlo_mode { 5978 5935 RTW89_MLO_MODE_MLSR = 0, 5936 + RTW89_MLO_MODE_EMLSR = 1, 5979 5937 5980 5938 NUM_OF_RTW89_MLO_MODE, 5981 5939 }; ··· 6049 6005 6050 6006 struct list_head tx_waits; 6051 6007 struct wiphy_delayed_work tx_wait_work; 6008 + 6009 + struct rtw89_tx_rpt tx_rpt; 6052 6010 6053 6011 struct rtw89_cam_info cam_info; 6054 6012 ··· 6125 6079 struct rtw89_btc btc; 6126 6080 enum rtw89_ps_mode ps_mode; 6127 6081 bool lps_enabled; 6082 + u8 ps_hang_cnt; 6128 6083 6129 6084 struct rtw89_wow_param wow; 6130 6085 ··· 6135 6088 int napi_budget_countdown; 6136 6089 6137 6090 struct rtw89_debugfs *debugfs; 6091 + struct rtw89_vif *pure_monitor_mode_vif; 6138 6092 6139 6093 /* HCI related data, keep last */ 6140 6094 u8 priv[] __aligned(sizeof(void *)); ··· 6143 6095 6144 6096 struct rtw89_link_conf_container { 6145 6097 struct ieee80211_bss_conf *link_conf[IEEE80211_MLD_MAX_NUM_LINKS]; 6098 + }; 6099 + 6100 + struct rtw89_vif_ml_trans { 6101 + u16 mediate_links; 6102 + u16 links_to_del; 6103 + u16 links_to_add; 6146 6104 }; 6147 6105 6148 6106 #define RTW89_VIF_IDLE_LINK_ID 0 ··· 6173 6119 bool offchan; 6174 6120 6175 6121 enum rtw89_mlo_mode mlo_mode; 6122 + struct rtw89_vif_ml_trans ml_trans; 6176 6123 6177 6124 struct list_head dlink_pool; 6178 6125 u8 links_inst_valid_num; ··· 6346 6291 static inline void rtw89_hci_reset(struct rtw89_dev *rtwdev) 6347 6292 { 6348 6293 rtwdev->hci.ops->reset(rtwdev); 6294 + /* hci.ops->reset must complete all pending TX wait SKBs */ 6349 6295 rtw89_tx_wait_list_clear(rtwdev); 6350 6296 } 6351 6297 ··· 6674 6618 mutex_lock(&rtwdev->rf_mutex); 6675 6619 rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data); 6676 6620 mutex_unlock(&rtwdev->rf_mutex); 6621 + } 6622 + 6623 + static inline u32 rtw89_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr) 6624 + { 6625 + if (rtwdev->hci.type != RTW89_HCI_TYPE_PCIE || 6626 + !rtwdev->hci.ops->read32_pci_cfg) 6627 + return RTW89_R32_EA; 6628 + 6629 + return rtwdev->hci.ops->read32_pci_cfg(rtwdev, addr); 6677 6630 } 6678 6631 6679 6632 static inline struct ieee80211_txq *rtw89_txq_to_txq(struct rtw89_txq *rtwtxq) ··· 7049 6984 } 7050 6985 7051 6986 static inline 7052 - void rtw89_chip_bb_preinit(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 6987 + void rtw89_chip_bb_preinit(struct rtw89_dev *rtwdev) 7053 6988 { 7054 6989 const struct rtw89_chip_info *chip = rtwdev->chip; 7055 6990 7056 - if (chip->ops->bb_preinit) 7057 - chip->ops->bb_preinit(rtwdev, phy_idx); 6991 + if (!chip->ops->bb_preinit) 6992 + return; 6993 + 6994 + chip->ops->bb_preinit(rtwdev, RTW89_PHY_0); 6995 + 6996 + if (rtwdev->dbcc_en) 6997 + chip->ops->bb_preinit(rtwdev, RTW89_PHY_1); 7058 6998 } 7059 6999 7060 7000 static inline ··· 7311 7241 { 7312 7242 const struct rtw89_chip_info *chip = rtwdev->chip; 7313 7243 7314 - return chip->ops->get_ch_dma(rtwdev, qsel); 7244 + return chip->ops->get_ch_dma[rtwdev->hci.type](rtwdev, qsel); 7315 7245 } 7316 7246 7317 7247 static inline ··· 7442 7372 return dev_alloc_skb(length); 7443 7373 } 7444 7374 7375 + static inline bool rtw89_core_is_tx_wait(struct rtw89_dev *rtwdev, 7376 + struct rtw89_tx_skb_data *skb_data) 7377 + { 7378 + return rcu_access_pointer(skb_data->wait); 7379 + } 7380 + 7445 7381 static inline bool rtw89_core_tx_wait_complete(struct rtw89_dev *rtwdev, 7446 7382 struct rtw89_tx_skb_data *skb_data, 7447 - bool tx_done) 7383 + u8 tx_status) 7448 7384 { 7449 7385 struct rtw89_tx_wait_info *wait; 7450 - bool ret = false; 7451 7386 7452 - rcu_read_lock(); 7387 + guard(rcu)(); 7453 7388 7454 7389 wait = rcu_dereference(skb_data->wait); 7455 7390 if (!wait) 7456 - goto out; 7391 + return false; 7457 7392 7458 - ret = true; 7459 - wait->tx_done = tx_done; 7393 + wait->tx_done = tx_status == RTW89_TX_DONE; 7460 7394 /* Don't access skb anymore after completion */ 7461 7395 complete_all(&wait->completion); 7462 - 7463 - out: 7464 - rcu_read_unlock(); 7465 - return ret; 7396 + return true; 7466 7397 } 7467 7398 7468 7399 static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev) ··· 7566 7495 void *txdesc); 7567 7496 u8 rtw89_core_get_ch_dma(struct rtw89_dev *rtwdev, u8 qsel); 7568 7497 u8 rtw89_core_get_ch_dma_v1(struct rtw89_dev *rtwdev, u8 qsel); 7498 + u8 rtw89_core_get_ch_dma_v2(struct rtw89_dev *rtwdev, u8 qsel); 7569 7499 void rtw89_core_rx(struct rtw89_dev *rtwdev, 7570 7500 struct rtw89_rx_desc_info *desc_info, 7571 7501 struct sk_buff *skb);
+299
drivers/net/wireless/realtek/rtw89/debug.c
··· 87 87 struct rtw89_debugfs_priv disable_dm; 88 88 struct rtw89_debugfs_priv mlo_mode; 89 89 struct rtw89_debugfs_priv beacon_info; 90 + struct rtw89_debugfs_priv diag_mac; 90 91 }; 91 92 92 93 struct rtw89_debugfs_iter_data { ··· 4362 4361 return count; 4363 4362 } 4364 4363 4364 + enum __diag_mac_cmd { 4365 + __CMD_EQUALV, 4366 + __CMD_EQUALO, 4367 + __CMD_NEQUALV, 4368 + __CMD_NEQUALO, 4369 + __CMD_SETEQUALV, 4370 + __CMD_SETEQUALO, 4371 + __CMD_CMPWCR, 4372 + __CMD_CMPWWD, 4373 + __CMD_NEQ_CMPWCR, 4374 + __CMD_NEQ_CMPWWD, 4375 + __CMD_INCREMENT, 4376 + __CMD_MESSAGE, 4377 + }; 4378 + 4379 + enum __diag_mac_io { 4380 + __IO_NORMAL, 4381 + __IO_NORMAL_PCIE, 4382 + __IO_NORMAL_USB, 4383 + __IO_NORMAL_SDIO, 4384 + __IO_PCIE_CFG, 4385 + __IO_SDIO_CCCR, 4386 + }; 4387 + 4388 + struct __diag_mac_rule_header { 4389 + u8 sheet; 4390 + u8 cmd; 4391 + u8 seq_major; 4392 + u8 seq_minor; 4393 + u8 io_band; 4394 + #define __DIAG_MAC_IO GENMASK(3, 0) 4395 + #define __DIAG_MAC_N_BAND BIT(4) 4396 + #define __DIAG_MAC_HAS_BAND BIT(5) 4397 + u8 len; /* include header. Unit: 4 bytes */ 4398 + u8 rsvd[2]; 4399 + } __packed; 4400 + 4401 + struct __diag_mac_rule_equal { 4402 + struct __diag_mac_rule_header header; 4403 + __le32 addr; 4404 + __le32 addr_name_offset; 4405 + __le32 mask; 4406 + __le32 val; 4407 + __le32 msg_offset; 4408 + u8 rsvd[4]; 4409 + } __packed; 4410 + 4411 + struct __diag_mac_rule_increment { 4412 + struct __diag_mac_rule_header header; 4413 + __le32 addr; 4414 + __le32 addr_name_offset; 4415 + __le32 mask; 4416 + __le16 sel; 4417 + __le16 delay; 4418 + __le32 msg_offset; 4419 + u8 rsvd[4]; 4420 + } __packed; 4421 + 4422 + struct __diag_mac_msg_buf { 4423 + __le16 len; 4424 + char string[]; 4425 + } __packed; 4426 + 4427 + static ssize_t rtw89_mac_diag_do_equalv(struct rtw89_dev *rtwdev, 4428 + char *buf, size_t bufsz, 4429 + const struct __diag_mac_rule_equal *r, 4430 + const void *msg_start, 4431 + u64 *positive_bmp) 4432 + { 4433 + const struct __diag_mac_msg_buf *name = msg_start + 4434 + le32_to_cpu(r->addr_name_offset); 4435 + const struct __diag_mac_msg_buf *msg = msg_start + 4436 + le32_to_cpu(r->msg_offset); 4437 + bool want_eq = r->header.cmd == __CMD_EQUALV; 4438 + char *p = buf, *end = buf + bufsz; 4439 + bool equal = false; 4440 + u32 val; 4441 + 4442 + *positive_bmp <<= 1; 4443 + 4444 + if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG) 4445 + val = rtw89_read32_pci_cfg(rtwdev, le32_to_cpu(r->addr)); 4446 + else 4447 + val = rtw89_read32(rtwdev, le32_to_cpu(r->addr)); 4448 + 4449 + if ((val & le32_to_cpu(r->mask)) == le32_to_cpu(r->val)) 4450 + equal = true; 4451 + 4452 + if (want_eq == equal) { 4453 + *positive_bmp |= BIT(0); 4454 + return p - buf; 4455 + } 4456 + 4457 + p += scnprintf(p, end - p, "sheet: %d, cmd: %d, Reg: %.*s => %x, %.*s\n", 4458 + r->header.sheet, r->header.cmd, le16_to_cpu(name->len), 4459 + name->string, val, le16_to_cpu(msg->len), msg->string); 4460 + 4461 + return p - buf; 4462 + } 4463 + 4464 + static ssize_t rtw89_mac_diag_do_increment(struct rtw89_dev *rtwdev, 4465 + char *buf, size_t bufsz, 4466 + const struct __diag_mac_rule_increment *r, 4467 + const void *msg_start, 4468 + u64 *positive_bmp) 4469 + { 4470 + const struct __diag_mac_msg_buf *name = msg_start + 4471 + le32_to_cpu(r->addr_name_offset); 4472 + const struct __diag_mac_msg_buf *msg = msg_start + 4473 + le32_to_cpu(r->msg_offset); 4474 + char *p = buf, *end = buf + bufsz; 4475 + u32 addr = le32_to_cpu(r->addr); 4476 + u32 mask = le32_to_cpu(r->mask); 4477 + u16 sel = le16_to_cpu(r->sel); 4478 + u32 val1, val2; 4479 + 4480 + *positive_bmp <<= 1; 4481 + 4482 + rtw89_write32(rtwdev, addr, sel); 4483 + 4484 + if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG) 4485 + val1 = rtw89_read32_pci_cfg(rtwdev, addr); 4486 + else 4487 + val1 = rtw89_read32(rtwdev, addr); 4488 + 4489 + mdelay(le16_to_cpu(r->delay)); 4490 + 4491 + if (u8_get_bits(r->header.io_band, __DIAG_MAC_IO) == __IO_PCIE_CFG) 4492 + val2 = rtw89_read32_pci_cfg(rtwdev, addr); 4493 + else 4494 + val2 = rtw89_read32(rtwdev, addr); 4495 + 4496 + if ((val2 & mask) > (val1 & mask)) { 4497 + *positive_bmp |= BIT(0); 4498 + return p - buf; 4499 + } 4500 + 4501 + p += scnprintf(p, end - p, "sheet: %d, cmd: %d, Reg: %.*s [%d]=> %x, %.*s\n", 4502 + r->header.sheet, r->header.cmd, le16_to_cpu(name->len), 4503 + name->string, le16_to_cpu(r->sel), val1, 4504 + le16_to_cpu(msg->len), msg->string); 4505 + 4506 + return p - buf; 4507 + } 4508 + 4509 + static bool rtw89_mac_diag_match_hci(struct rtw89_dev *rtwdev, 4510 + const struct __diag_mac_rule_header *rh) 4511 + { 4512 + switch (u8_get_bits(rh->io_band, __DIAG_MAC_IO)) { 4513 + case __IO_NORMAL: 4514 + default: 4515 + return true; 4516 + case __IO_NORMAL_PCIE: 4517 + case __IO_PCIE_CFG: 4518 + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) 4519 + return true; 4520 + break; 4521 + case __IO_NORMAL_USB: 4522 + if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) 4523 + return true; 4524 + break; 4525 + case __IO_NORMAL_SDIO: 4526 + case __IO_SDIO_CCCR: 4527 + if (rtwdev->hci.type == RTW89_HCI_TYPE_SDIO) 4528 + return true; 4529 + break; 4530 + } 4531 + 4532 + return false; 4533 + } 4534 + 4535 + static bool rtw89_mac_diag_match_band(struct rtw89_dev *rtwdev, 4536 + const struct __diag_mac_rule_header *rh) 4537 + { 4538 + u8 active_bands; 4539 + bool has_band; 4540 + u8 band; 4541 + 4542 + has_band = u8_get_bits(rh->io_band, __DIAG_MAC_HAS_BAND); 4543 + if (!has_band) 4544 + return true; 4545 + 4546 + band = u8_get_bits(rh->io_band, __DIAG_MAC_N_BAND); 4547 + active_bands = rtw89_get_active_phy_bitmap(rtwdev); 4548 + 4549 + if (active_bands & BIT(band)) 4550 + return true; 4551 + 4552 + return false; 4553 + } 4554 + 4555 + static ssize_t rtw89_mac_diag_iter_all(struct rtw89_dev *rtwdev, 4556 + char *buf, size_t bufsz) 4557 + { 4558 + const struct rtw89_fw_element_hdr *elm = rtwdev->fw.elm_info.diag_mac; 4559 + u32 n_plains = 0, n_rules = 0, n_positive = 0, n_ignore = 0; 4560 + char *p = buf, *end = buf + bufsz, *p_rewind; 4561 + const void *rule, *rule_end; 4562 + u32 elm_size, rule_size; 4563 + const void *msg_start; 4564 + u64 positive_bmp = 0; 4565 + u8 prev_sheet = 0; 4566 + u8 prev_seq = 0; 4567 + int limit; 4568 + 4569 + if (!elm) { 4570 + p += scnprintf(p, end - p, "No diag_mac entry\n"); 4571 + goto out; 4572 + } 4573 + 4574 + rule_size = le32_to_cpu(elm->u.diag_mac.rule_size); 4575 + elm_size = le32_to_cpu(elm->size); 4576 + 4577 + if (ALIGN(rule_size, 16) > elm_size) { 4578 + p += scnprintf(p, end - p, "rule size (%u) exceed elm_size (%u)\n", 4579 + ALIGN(rule_size, 16), elm_size); 4580 + goto out; 4581 + } 4582 + 4583 + rule = &elm->u.diag_mac.rules_and_msgs[0]; 4584 + rule_end = &elm->u.diag_mac.rules_and_msgs[rule_size]; 4585 + msg_start = &elm->u.diag_mac.rules_and_msgs[ALIGN(rule_size, 16)]; 4586 + 4587 + for (limit = 0; limit < 5000 && rule < rule_end; limit++) { 4588 + const struct __diag_mac_rule_header *rh = rule; 4589 + u8 sheet = rh->sheet; 4590 + u8 seq = rh->seq_major; 4591 + 4592 + if (!rtw89_mac_diag_match_hci(rtwdev, rh) || 4593 + !rtw89_mac_diag_match_band(rtwdev, rh)) { 4594 + n_ignore++; 4595 + goto next; 4596 + } 4597 + 4598 + if (!seq || prev_sheet != sheet || prev_seq != seq) { 4599 + if (positive_bmp) { 4600 + n_positive++; 4601 + /* 4602 + * discard output for negative results if one in 4603 + * a sequence set is positive. 4604 + */ 4605 + if (p_rewind) 4606 + p = p_rewind; 4607 + } 4608 + p_rewind = seq ? p : NULL; 4609 + positive_bmp = 0; 4610 + n_rules++; 4611 + } 4612 + 4613 + switch (rh->cmd) { 4614 + case __CMD_EQUALV: 4615 + case __CMD_NEQUALV: 4616 + p += rtw89_mac_diag_do_equalv(rtwdev, p, end - p, rule, 4617 + msg_start, &positive_bmp); 4618 + break; 4619 + case __CMD_INCREMENT: 4620 + p += rtw89_mac_diag_do_increment(rtwdev, p, end - p, rule, 4621 + msg_start, &positive_bmp); 4622 + break; 4623 + default: 4624 + p += scnprintf(p, end - p, "unknown rule cmd %u\n", rh->cmd); 4625 + break; 4626 + } 4627 + 4628 + next: 4629 + n_plains++; 4630 + rule += rh->len * 4; 4631 + prev_seq = seq; 4632 + prev_sheet = sheet; 4633 + } 4634 + 4635 + if (positive_bmp) { 4636 + n_positive++; 4637 + if (p_rewind) 4638 + p = p_rewind; 4639 + } 4640 + 4641 + p += scnprintf(p, end - p, "\nPlain(Ignore)/Rules/Positive: %u(%u)/%u/%u\n", 4642 + n_plains, n_ignore, n_rules, n_positive); 4643 + 4644 + out: 4645 + return p - buf; 4646 + } 4647 + 4648 + static ssize_t 4649 + rtw89_debug_priv_diag_mac_get(struct rtw89_dev *rtwdev, 4650 + struct rtw89_debugfs_priv *debugfs_priv, 4651 + char *buf, size_t bufsz) 4652 + { 4653 + lockdep_assert_wiphy(rtwdev->hw->wiphy); 4654 + 4655 + rtw89_leave_lps(rtwdev); 4656 + 4657 + return rtw89_mac_diag_iter_all(rtwdev, buf, bufsz); 4658 + } 4659 + 4365 4660 static ssize_t 4366 4661 rtw89_debug_priv_beacon_info_get(struct rtw89_dev *rtwdev, 4367 4662 struct rtw89_debugfs_priv *debugfs_priv, ··· 4775 4478 .disable_dm = rtw89_debug_priv_set_and_get(disable_dm, RWLOCK), 4776 4479 .mlo_mode = rtw89_debug_priv_set_and_get(mlo_mode, RWLOCK), 4777 4480 .beacon_info = rtw89_debug_priv_get(beacon_info), 4481 + .diag_mac = rtw89_debug_priv_get(diag_mac, RSIZE_16K, RLOCK), 4778 4482 }; 4779 4483 4780 4484 #define rtw89_debugfs_add(name, mode, fopname, parent) \ ··· 4822 4524 rtw89_debugfs_add_rw(disable_dm); 4823 4525 rtw89_debugfs_add_rw(mlo_mode); 4824 4526 rtw89_debugfs_add_r(beacon_info); 4527 + rtw89_debugfs_add_r(diag_mac); 4825 4528 } 4826 4529 4827 4530 void rtw89_debugfs_init(struct rtw89_dev *rtwdev)
+118 -51
drivers/net/wireless/realtek/rtw89/fw.c
··· 161 161 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_W7_DYN_HDR); 162 162 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_W7_IDMEM_SHARE_MODE); 163 163 164 + if (chip->chip_gen == RTW89_CHIP_AX) 165 + info->part_size = FWDL_SECTION_PER_PKT_LEN; 166 + else 167 + info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_W7_PART_SIZE); 168 + 164 169 if (info->dynamic_hdr_en) { 165 170 info->hdr_len = le32_get_bits(fw_hdr->w3, FW_HDR_W3_LEN); 166 171 info->dynamic_hdr_len = info->hdr_len - base_hdr_len; ··· 444 439 struct rtw89_fw_bin_info *info) 445 440 { 446 441 const struct rtw89_fw_hdr_v1 *fw_hdr = (const struct rtw89_fw_hdr_v1 *)fw; 442 + const struct rtw89_chip_info *chip = rtwdev->chip; 447 443 struct rtw89_fw_hdr_section_info *section_info; 448 444 const struct rtw89_fw_dynhdr_hdr *fwdynhdr; 449 445 const struct rtw89_fw_hdr_section_v1 *section; ··· 460 454 base_hdr_len = struct_size(fw_hdr, sections, info->section_num); 461 455 info->dynamic_hdr_en = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_DYN_HDR); 462 456 info->idmem_share_mode = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_IDMEM_SHARE_MODE); 457 + 458 + if (chip->chip_gen == RTW89_CHIP_AX) 459 + info->part_size = FWDL_SECTION_PER_PKT_LEN; 460 + else 461 + info->part_size = le32_get_bits(fw_hdr->w7, FW_HDR_V1_W7_PART_SIZE); 463 462 464 463 if (info->dynamic_hdr_en) { 465 464 info->hdr_len = le32_get_bits(fw_hdr->w5, FW_HDR_V1_W5_HDR_SIZE); ··· 881 870 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 76, 0, LPS_DACK_BY_C2H_REG), 882 871 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 79, 0, CRASH_TRIGGER_TYPE_1), 883 872 __CFG_FW_FEAT(RTL8922A, ge, 0, 35, 80, 0, BEACON_TRACKING), 873 + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 84, 0, ADDR_CAM_V0), 884 874 }; 885 875 886 876 static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, ··· 1310 1298 return 0; 1311 1299 } 1312 1300 1301 + static 1302 + int rtw89_recognize_diag_mac_from_elm(struct rtw89_dev *rtwdev, 1303 + const struct rtw89_fw_element_hdr *elm, 1304 + const union rtw89_fw_element_arg arg) 1305 + { 1306 + struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; 1307 + 1308 + elm_info->diag_mac = elm; 1309 + 1310 + return 0; 1311 + } 1312 + 1313 1313 static const struct rtw89_fw_element_handler __fw_element_handlers[] = { 1314 1314 [RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm, 1315 1315 { .fw_type = RTW89_FW_BBMCU0 }, NULL}, ··· 1409 1385 }, 1410 1386 [RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ] = { 1411 1387 rtw89_build_afe_pwr_seq_from_elm, {}, "AFE", 1388 + }, 1389 + [RTW89_FW_ELEMENT_ID_DIAG_MAC] = { 1390 + rtw89_recognize_diag_mac_from_elm, {}, NULL, 1412 1391 }, 1413 1392 }; 1414 1393 ··· 1528 1501 struct rtw89_fw_hdr_section *section; 1529 1502 int i; 1530 1503 1531 - le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN, 1532 - FW_HDR_W7_PART_SIZE); 1504 + le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_W7_PART_SIZE); 1533 1505 1534 1506 for (i = 0; i < info->section_num; i++) { 1535 1507 section_info = &info->section_info[i]; ··· 1553 1527 u8 dst_sec_idx = 0; 1554 1528 u8 sec_idx; 1555 1529 1556 - le32p_replace_bits(&fw_hdr->w7, FWDL_SECTION_PER_PKT_LEN, 1557 - FW_HDR_V1_W7_PART_SIZE); 1530 + le32p_replace_bits(&fw_hdr->w7, info->part_size, FW_HDR_V1_W7_PART_SIZE); 1558 1531 1559 1532 for (sec_idx = 0; sec_idx < info->section_num; sec_idx++) { 1560 1533 section_info = &info->section_info[sec_idx]; ··· 1655 1630 } 1656 1631 1657 1632 static int __rtw89_fw_download_main(struct rtw89_dev *rtwdev, 1658 - struct rtw89_fw_hdr_section_info *info) 1633 + struct rtw89_fw_hdr_section_info *info, 1634 + u32 part_size) 1659 1635 { 1660 1636 struct sk_buff *skb; 1661 1637 const u8 *section = info->addr; ··· 1677 1651 } 1678 1652 1679 1653 if (info->key_addr && info->key_len) { 1680 - if (residue_len > FWDL_SECTION_PER_PKT_LEN || info->len < info->key_len) 1654 + if (residue_len > part_size || info->len < info->key_len) 1681 1655 rtw89_warn(rtwdev, 1682 1656 "ignore to copy key data because of len %d, %d, %d, %d\n", 1683 - info->len, FWDL_SECTION_PER_PKT_LEN, 1657 + info->len, part_size, 1684 1658 info->key_len, residue_len); 1685 1659 else 1686 1660 copy_key = true; 1687 1661 } 1688 1662 1689 1663 while (residue_len) { 1690 - if (residue_len >= FWDL_SECTION_PER_PKT_LEN) 1691 - pkt_len = FWDL_SECTION_PER_PKT_LEN; 1692 - else 1693 - pkt_len = residue_len; 1664 + pkt_len = min(residue_len, part_size); 1694 1665 1695 1666 skb = rtw89_fw_h2c_alloc_skb_no_hdr(rtwdev, pkt_len); 1696 1667 if (!skb) { ··· 1742 1719 int ret; 1743 1720 1744 1721 while (section_num--) { 1745 - ret = __rtw89_fw_download_main(rtwdev, section_info); 1722 + ret = __rtw89_fw_download_main(rtwdev, section_info, info->part_size); 1746 1723 if (ret) 1747 1724 return ret; 1748 1725 section_info++; ··· 2133 2110 2134 2111 } 2135 2112 2136 - #define H2C_CAM_LEN 60 2137 2113 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, 2138 - struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr) 2114 + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr, 2115 + enum rtw89_upd_mode upd_mode) 2139 2116 { 2117 + const struct rtw89_chip_info *chip = rtwdev->chip; 2118 + struct rtw89_h2c_addr_cam_v0 *h2c_v0; 2119 + struct rtw89_h2c_addr_cam *h2c; 2120 + u32 len = sizeof(*h2c); 2140 2121 struct sk_buff *skb; 2122 + u8 ver = U8_MAX; 2141 2123 int ret; 2142 2124 2143 - skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_CAM_LEN); 2125 + if (RTW89_CHK_FW_FEATURE(ADDR_CAM_V0, &rtwdev->fw) || 2126 + chip->chip_gen == RTW89_CHIP_AX) { 2127 + len = sizeof(*h2c_v0); 2128 + ver = 0; 2129 + } 2130 + 2131 + skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); 2144 2132 if (!skb) { 2145 2133 rtw89_err(rtwdev, "failed to alloc skb for fw dl\n"); 2146 2134 return -ENOMEM; 2147 2135 } 2148 - skb_put(skb, H2C_CAM_LEN); 2149 - rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, scan_mac_addr, 2150 - skb->data); 2151 - rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, skb->data); 2136 + skb_put(skb, len); 2137 + h2c_v0 = (struct rtw89_h2c_addr_cam_v0 *)skb->data; 2152 2138 2139 + rtw89_cam_fill_addr_cam_info(rtwdev, rtwvif_link, rtwsta_link, 2140 + scan_mac_addr, h2c_v0); 2141 + rtw89_cam_fill_bssid_cam_info(rtwdev, rtwvif_link, rtwsta_link, h2c_v0); 2142 + 2143 + if (ver == 0) 2144 + goto hdr; 2145 + 2146 + h2c = (struct rtw89_h2c_addr_cam *)skb->data; 2147 + h2c->w15 = le32_encode_bits(upd_mode, ADDR_CAM_W15_UPD_MODE); 2148 + 2149 + hdr: 2153 2150 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, 2154 2151 H2C_CAT_MAC, 2155 2152 H2C_CL_MAC_ADDR_CAM_UPDATE, 2156 2153 H2C_FUNC_MAC_ADDR_CAM_UPD, 0, 1, 2157 - H2C_CAM_LEN); 2154 + len); 2158 2155 2159 2156 ret = rtw89_h2c_tx(rtwdev, skb, false); 2160 2157 if (ret) { ··· 3208 3165 SET_CMC_TBL_ANTSEL_C(skb->data, 0); 3209 3166 SET_CMC_TBL_ANTSEL_D(skb->data, 0); 3210 3167 } 3168 + SET_CMC_TBL_MGQ_RPT_EN(skb->data, rtwdev->hci.tx_rpt_enabled); 3211 3169 SET_CMC_TBL_DOPPLER_CTRL(skb->data, 0); 3212 3170 SET_CMC_TBL_TXPWR_TOLERENCE(skb->data, 0); 3213 3171 if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE) ··· 3254 3210 h2c->c0 = le32_encode_bits(mac_id, CCTLINFO_G7_C0_MACID) | 3255 3211 le32_encode_bits(1, CCTLINFO_G7_C0_OP); 3256 3212 3257 - h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE); 3213 + h2c->w0 = le32_encode_bits(4, CCTLINFO_G7_W0_DATARATE) | 3214 + le32_encode_bits(rtwdev->hci.tx_rpt_enabled, CCTLINFO_G7_W0_MGQ_RPT_EN); 3258 3215 h2c->m0 = cpu_to_le32(CCTLINFO_G7_W0_ALL); 3259 3216 3260 3217 h2c->w1 = le32_encode_bits(4, CCTLINFO_G7_W1_DATA_RTY_LOWEST_RATE) | ··· 4760 4715 struct rtw89_h2c_ra_v1 *h2c_v1; 4761 4716 struct rtw89_h2c_ra *h2c; 4762 4717 u32 len = sizeof(*h2c); 4763 - bool format_v1 = false; 4764 4718 struct sk_buff *skb; 4719 + u8 ver = U8_MAX; 4765 4720 int ret; 4766 4721 4767 - if (chip->chip_gen == RTW89_CHIP_BE) { 4722 + if (chip->chip_gen == RTW89_CHIP_AX) { 4723 + len = sizeof(*h2c); 4724 + ver = 0; 4725 + } else { 4768 4726 len = sizeof(*h2c_v1); 4769 - format_v1 = true; 4727 + ver = 1; 4770 4728 } 4771 4729 4772 4730 skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len); ··· 4801 4753 h2c->w3 = le32_encode_bits(ra->fix_giltf_en, RTW89_H2C_RA_W3_FIX_GILTF_EN) | 4802 4754 le32_encode_bits(ra->fix_giltf, RTW89_H2C_RA_W3_FIX_GILTF); 4803 4755 4804 - if (!format_v1) 4805 - goto csi; 4806 - 4807 - h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c; 4808 - h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) | 4809 - le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT); 4810 - 4811 - csi: 4812 - if (!csi) 4813 - goto done; 4756 + if (!csi || ver >= 1) 4757 + goto next_v1; 4814 4758 4815 4759 h2c->w2 |= le32_encode_bits(1, RTW89_H2C_RA_W2_BFEE_CSI_CTL); 4816 4760 h2c->w3 |= le32_encode_bits(ra->band_num, RTW89_H2C_RA_W3_BAND_NUM) | ··· 4813 4773 le32_encode_bits(ra->csi_mode, RTW89_H2C_RA_W3_FIXED_CSI_MODE) | 4814 4774 le32_encode_bits(ra->csi_gi_ltf, RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF) | 4815 4775 le32_encode_bits(ra->csi_bw, RTW89_H2C_RA_W3_FIXED_CSI_BW); 4776 + 4777 + next_v1: 4778 + if (ver < 1) 4779 + goto done; 4780 + 4781 + h2c->w3 |= le32_encode_bits(ra->partial_bw_er, 4782 + RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER) | 4783 + le32_encode_bits(ra->band, RTW89_H2C_RA_V1_W3_BAND); 4784 + 4785 + h2c_v1 = (struct rtw89_h2c_ra_v1 *)h2c; 4786 + h2c_v1->w4 = le32_encode_bits(ra->mode_ctrl, RTW89_H2C_RA_V1_W4_MODE_EHT) | 4787 + le32_encode_bits(ra->bw_cap, RTW89_H2C_RA_V1_W4_BW_EHT); 4816 4788 4817 4789 done: 4818 4790 rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C, ··· 6943 6891 struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev, 6944 6892 c2h_work); 6945 6893 struct sk_buff *skb, *tmp; 6894 + struct sk_buff_head c2hq; 6895 + unsigned long flags; 6946 6896 6947 6897 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6948 6898 6949 - skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { 6950 - skb_unlink(skb, &rtwdev->c2h_queue); 6899 + __skb_queue_head_init(&c2hq); 6900 + 6901 + spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); 6902 + skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq); 6903 + spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); 6904 + 6905 + skb_queue_walk_safe(&c2hq, skb, tmp) { 6951 6906 rtw89_fw_c2h_cmd_handle(rtwdev, skb); 6952 6907 dev_kfree_skb_any(skb); 6953 6908 } ··· 6964 6905 { 6965 6906 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 6966 6907 struct sk_buff *skb, *tmp; 6967 - int limit; 6908 + struct sk_buff_head c2hq; 6909 + unsigned long flags; 6968 6910 6969 6911 lockdep_assert_wiphy(rtwdev->hw->wiphy); 6970 6912 6971 - limit = skb_queue_len(&rtwdev->c2h_queue); 6913 + __skb_queue_head_init(&c2hq); 6972 6914 6973 - skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { 6915 + spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); 6916 + skb_queue_splice_init(&rtwdev->c2h_queue, &c2hq); 6917 + spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); 6918 + 6919 + skb_queue_walk_safe(&c2hq, skb, tmp) { 6974 6920 struct rtw89_fw_c2h_attr *attr = RTW89_SKB_C2H_CB(skb); 6975 - 6976 - if (--limit < 0) 6977 - return; 6978 6921 6979 6922 if (!attr->is_scan_event || attr->scan_seq == scan_info->seq) 6980 6923 continue; ··· 6985 6924 "purge obsoleted scan event with seq=%d (cur=%d)\n", 6986 6925 attr->scan_seq, scan_info->seq); 6987 6926 6988 - skb_unlink(skb, &rtwdev->c2h_queue); 6927 + __skb_unlink(skb, &c2hq); 6989 6928 dev_kfree_skb_any(skb); 6990 6929 } 6930 + 6931 + spin_lock_irqsave(&rtwdev->c2h_queue.lock, flags); 6932 + skb_queue_splice(&c2hq, &rtwdev->c2h_queue); 6933 + spin_unlock_irqrestore(&rtwdev->c2h_queue.lock, flags); 6991 6934 } 6992 6935 6993 6936 static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, ··· 7846 7781 struct ieee80211_channel *channel; 7847 7782 struct list_head chan_list; 7848 7783 enum rtw89_chan_type type; 7784 + bool chan_by_rnr; 7849 7785 bool random_seq; 7850 7786 int ret; 7851 7787 u32 idx; 7852 7788 7853 7789 random_seq = !!(req->flags & NL80211_SCAN_FLAG_RANDOM_SN); 7790 + chan_by_rnr = rtwdev->chip->support_rnr && 7791 + (req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ); 7854 7792 INIT_LIST_HEAD(&chan_list); 7855 7793 7856 7794 for (idx = 0; idx < req->n_channels; idx++) { 7857 7795 channel = req->channels[idx]; 7796 + 7797 + if (channel->band == NL80211_BAND_6GHZ && 7798 + !cfg80211_channel_is_psc(channel) && chan_by_rnr) 7799 + continue; 7800 + 7858 7801 ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); 7859 7802 if (!ch_info) { 7860 7803 ret = -ENOMEM; ··· 8110 8037 struct rtw89_vif_link *rtwvif_link, 8111 8038 struct ieee80211_scan_request *scan_req) 8112 8039 { 8113 - const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 8114 8040 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); 8115 8041 struct cfg80211_scan_request *req = &scan_req->req; 8116 8042 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, ··· 8121 8049 }; 8122 8050 u32 rx_fltr = rtwdev->hal.rx_fltr; 8123 8051 u8 mac_addr[ETH_ALEN]; 8124 - u32 reg; 8125 8052 int ret; 8126 8053 8127 8054 /* clone op and keep it during scan */ ··· 8160 8089 rx_fltr &= ~B_AX_A_BC; 8161 8090 rx_fltr &= ~B_AX_A_A1_MATCH; 8162 8091 8163 - reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); 8164 - rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rx_fltr); 8092 + rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rx_fltr); 8165 8093 8166 8094 rtw89_chanctx_pause(rtwdev, &pause_parm); 8167 8095 rtw89_phy_dig_suspend(rtwdev); ··· 8178 8108 8179 8109 static int rtw89_hw_scan_complete_cb(struct rtw89_dev *rtwdev, void *data) 8180 8110 { 8181 - const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 8182 8111 enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev); 8183 8112 struct rtw89_hw_scan_complete_cb_data *cb_data = data; 8184 8113 struct rtw89_vif_link *rtwvif_link = cb_data->rtwvif_link; 8185 8114 struct cfg80211_scan_info info = { 8186 8115 .aborted = cb_data->aborted, 8187 8116 }; 8188 - u32 reg; 8189 8117 8190 8118 if (!rtwvif_link) 8191 8119 return -EINVAL; 8192 8120 8193 - reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, rtwvif_link->mac_idx); 8194 - rtw89_write32_mask(rtwdev, reg, B_AX_RX_FLTR_CFG_MASK, rtwdev->hal.rx_fltr); 8121 + rtw89_mac_set_rx_fltr(rtwdev, rtwvif_link->mac_idx, rtwdev->hal.rx_fltr); 8195 8122 8196 8123 rtw89_core_scan_complete(rtwdev, rtwvif_link, true); 8197 8124 ieee80211_scan_completed(rtwdev->hw, &info);
+66 -1
drivers/net/wireless/realtek/rtw89/fw.h
··· 297 297 298 298 struct rtw89_fw_bin_info { 299 299 u8 section_num; 300 + u32 part_size; 300 301 u32 hdr_len; 301 302 bool dynamic_hdr_en; 302 303 u32 dynamic_hdr_len; ··· 447 446 #define RTW89_H2C_RA_W3_FIXED_CSI_MODE GENMASK(25, 24) 448 447 #define RTW89_H2C_RA_W3_FIXED_CSI_GI_LTF GENMASK(28, 26) 449 448 #define RTW89_H2C_RA_W3_FIXED_CSI_BW GENMASK(31, 29) 449 + #define RTW89_H2C_RA_V1_W3_PARTIAL_BW_SU_ER BIT(15) 450 + #define RTW89_H2C_RA_V1_W3_FIXED_CSI_RATE_L GENMASK(23, 16) 451 + #define RTW89_H2C_RA_V1_W3_IS_NOISY BIT(24) 452 + #define RTW89_H2C_RA_V1_W3_PSRA_EN BIT(25) 453 + #define RTW89_H2C_RA_V1_W3_MACID_MSB GENMASK(28, 27) 454 + #define RTW89_H2C_RA_V1_W3_BAND GENMASK(30, 29) 455 + #define RTW89_H2C_RA_V1_W3_NEW_DBGREG BIT(31) 450 456 451 457 struct rtw89_h2c_ra_v1 { 452 458 struct rtw89_h2c_ra v0; ··· 3655 3647 #define RTW89_C2H_FW_LOG_SIGNATURE 0xA5A5 3656 3648 #define RTW89_C2H_FW_LOG_STR_BUF_SIZE 512 3657 3649 3650 + struct rtw89_c2h_bcn_upd_done { 3651 + struct rtw89_c2h_hdr hdr; 3652 + __le32 w2; 3653 + } __packed; 3654 + 3655 + #define RTW89_C2H_BCN_UPD_DONE_W2_PORT GENMASK(2, 0) 3656 + #define RTW89_C2H_BCN_UPD_DONE_W2_MBSSID GENMASK(6, 3) 3657 + #define RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX BIT(7) 3658 + 3658 3659 struct rtw89_c2h_mac_bcnfltr_rpt { 3659 3660 __le32 w0; 3660 3661 __le32 w1; ··· 3763 3746 le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(7, 2)) 3764 3747 #define RTW89_GET_MAC_C2H_MCC_REQ_ACK_H2C_FUNC(c2h) \ 3765 3748 le32_get_bits(*((const __le32 *)(c2h) + 2), GENMASK(15, 8)) 3749 + 3750 + struct rtw89_c2h_mac_tx_rpt { 3751 + struct rtw89_c2h_hdr hdr; 3752 + __le32 w2; 3753 + __le32 w3; 3754 + __le32 w4; 3755 + __le32 w5; 3756 + __le32 w6; 3757 + __le32 w7; 3758 + } __packed; 3759 + 3760 + #define RTW89_C2H_MAC_TX_RPT_W2_TX_STATE GENMASK(7, 6) 3761 + #define RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE GENMASK(11, 8) 3762 + #define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT GENMASK(13, 8) 3763 + #define RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1 GENMASK(15, 10) 3764 + 3765 + struct rtw89_c2h_mac_tx_rpt_v2 { 3766 + struct rtw89_c2h_hdr hdr; 3767 + __le32 w2; 3768 + __le32 w3; 3769 + __le32 w4; 3770 + __le32 w5; 3771 + __le32 w6; 3772 + __le32 w7; 3773 + __le32 w8; 3774 + __le32 w9; 3775 + __le32 w10; 3776 + __le32 w11; 3777 + __le32 w12; 3778 + __le32 w13; 3779 + __le32 w14; 3780 + __le32 w15; 3781 + __le32 w16; 3782 + __le32 w17; 3783 + __le32 w18; 3784 + __le32 w19; 3785 + } __packed; 3786 + 3787 + #define RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2 GENMASK(9, 8) 3788 + #define RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2 GENMASK(15, 12) 3789 + #define RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2 GENMASK(15, 10) 3766 3790 3767 3791 struct rtw89_mac_mcc_tsf_rpt { 3768 3792 u32 macid_x; ··· 4043 3985 RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_5GHZ = 25, 4044 3986 RTW89_FW_ELEMENT_ID_TXPWR_DA_LMT_RU_6GHZ = 26, 4045 3987 RTW89_FW_ELEMENT_ID_AFE_PWR_SEQ = 27, 3988 + RTW89_FW_ELEMENT_ID_DIAG_MAC = 28, 4046 3989 4047 3990 RTW89_FW_ELEMENT_ID_NUM, 4048 3991 }; ··· 4221 4162 __le32 val; 4222 4163 } __packed infos[]; 4223 4164 } __packed afe; 4165 + struct { 4166 + __le32 rule_size; 4167 + u8 rsvd[4]; 4168 + u8 rules_and_msgs[]; 4169 + } __packed diag_mac; 4224 4170 struct __rtw89_fw_txpwr_element txpwr; 4225 4171 struct __rtw89_fw_regd_element regd; 4226 4172 } __packed u; ··· 4887 4823 struct rtw89_vif_link *rtwvif_link, u32 offset); 4888 4824 int rtw89_fw_h2c_pwr_lvl(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); 4889 4825 int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif, 4890 - struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr); 4826 + struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr, 4827 + enum rtw89_upd_mode upd_mode); 4891 4828 int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev, 4892 4829 struct rtw89_vif_link *rtwvif_link, 4893 4830 struct rtw89_sta_link *rtwsta_link);
+184 -16
drivers/net/wireless/realtek/rtw89/mac.c
··· 12 12 #include "phy.h" 13 13 #include "ps.h" 14 14 #include "reg.h" 15 + #include "ser.h" 15 16 #include "util.h" 16 17 17 18 static const u32 rtw89_mac_mem_base_addrs_ax[RTW89_MAC_MEM_NUM] = { ··· 1295 1294 static int rtw89_mac_pwr_seq(struct rtw89_dev *rtwdev, 1296 1295 const struct rtw89_pwr_cfg * const *cfg_seq) 1297 1296 { 1297 + u8 intf_msk; 1298 1298 int ret; 1299 + 1300 + switch (rtwdev->hci.type) { 1301 + case RTW89_HCI_TYPE_PCIE: 1302 + intf_msk = PWR_INTF_MSK_PCIE; 1303 + break; 1304 + case RTW89_HCI_TYPE_USB: 1305 + intf_msk = PWR_INTF_MSK_USB; 1306 + break; 1307 + case RTW89_HCI_TYPE_SDIO: 1308 + intf_msk = PWR_INTF_MSK_SDIO; 1309 + break; 1310 + default: 1311 + return -EOPNOTSUPP; 1312 + } 1299 1313 1300 1314 for (; *cfg_seq; cfg_seq++) { 1301 1315 ret = rtw89_mac_sub_pwr_seq(rtwdev, BIT(rtwdev->hal.cv), 1302 - PWR_INTF_MSK_PCIE, *cfg_seq); 1316 + intf_msk, *cfg_seq); 1303 1317 if (ret) 1304 1318 return -EBUSY; 1305 1319 } ··· 1439 1423 if (!ret) 1440 1424 break; 1441 1425 1442 - if (i == RPWM_TRY_CNT - 1) 1426 + if (i == RPWM_TRY_CNT - 1) { 1443 1427 rtw89_err(rtwdev, "firmware failed to ack for %s ps mode\n", 1444 1428 enter ? "entering" : "leaving"); 1445 - else 1429 + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); 1430 + } else { 1446 1431 rtw89_debug(rtwdev, RTW89_DBG_UNEXP, 1447 1432 "%d time firmware failed to ack for %s ps mode\n", 1448 1433 i + 1, enter ? "entering" : "leaving"); 1434 + } 1449 1435 } 1450 1436 } 1451 1437 ··· 1669 1651 /* PCIE 64 */ 1670 1652 .wde_size0 = {RTW89_WDE_PG_64, 4095, 1,}, 1671 1653 .wde_size0_v1 = {RTW89_WDE_PG_64, 3328, 0, 0,}, 1654 + /* 8852A USB */ 1655 + .wde_size1 = {RTW89_WDE_PG_64, 768, 0,}, 1672 1656 /* DLFW */ 1673 1657 .wde_size4 = {RTW89_WDE_PG_64, 0, 4096,}, 1674 1658 .wde_size4_v1 = {RTW89_WDE_PG_64, 0, 3328, 0,}, ··· 1680 1660 .wde_size7 = {RTW89_WDE_PG_64, 510, 2,}, 1681 1661 /* DLFW */ 1682 1662 .wde_size9 = {RTW89_WDE_PG_64, 0, 1024,}, 1663 + /* 8852C USB3.0 */ 1664 + .wde_size17 = {RTW89_WDE_PG_64, 354, 30,}, 1683 1665 /* 8852C DLFW */ 1684 1666 .wde_size18 = {RTW89_WDE_PG_64, 0, 2048,}, 1685 1667 /* 8852C PCIE SCC */ ··· 1689 1667 .wde_size23 = {RTW89_WDE_PG_64, 1022, 2,}, 1690 1668 /* 8852B USB2.0/USB3.0 SCC */ 1691 1669 .wde_size25 = {RTW89_WDE_PG_64, 162, 94,}, 1670 + /* 8852C USB2.0 */ 1671 + .wde_size31 = {RTW89_WDE_PG_64, 384, 0,}, 1692 1672 /* PCIE */ 1693 1673 .ple_size0 = {RTW89_PLE_PG_128, 1520, 16,}, 1694 1674 .ple_size0_v1 = {RTW89_PLE_PG_128, 2688, 240, 212992,}, 1675 + /* 8852A USB */ 1676 + .ple_size1 = {RTW89_PLE_PG_128, 3184, 16,}, 1695 1677 .ple_size3_v1 = {RTW89_PLE_PG_128, 2928, 0, 212992,}, 1696 1678 /* DLFW */ 1697 1679 .ple_size4 = {RTW89_PLE_PG_128, 64, 1472,}, ··· 1704 1678 /* DLFW */ 1705 1679 .ple_size8 = {RTW89_PLE_PG_128, 64, 960,}, 1706 1680 .ple_size9 = {RTW89_PLE_PG_128, 2288, 16,}, 1681 + /* 8852C USB */ 1682 + .ple_size17 = {RTW89_PLE_PG_128, 3368, 24,}, 1707 1683 /* 8852C DLFW */ 1708 1684 .ple_size18 = {RTW89_PLE_PG_128, 2544, 16,}, 1709 1685 /* 8852C PCIE SCC */ ··· 1714 1686 .ple_size32 = {RTW89_PLE_PG_128, 620, 20,}, 1715 1687 /* 8852B USB3.0 SCC */ 1716 1688 .ple_size33 = {RTW89_PLE_PG_128, 632, 8,}, 1689 + /* 8852C USB2.0 */ 1690 + .ple_size34 = {RTW89_PLE_PG_128, 3374, 18,}, 1717 1691 /* PCIE 64 */ 1718 1692 .wde_qt0 = {3792, 196, 0, 107,}, 1719 1693 .wde_qt0_v1 = {3302, 6, 0, 20,}, 1694 + /* 8852A USB */ 1695 + .wde_qt1 = {512, 196, 0, 60,}, 1720 1696 /* DLFW */ 1721 1697 .wde_qt4 = {0, 0, 0, 0,}, 1722 1698 /* PCIE 64 */ 1723 1699 .wde_qt6 = {448, 48, 0, 16,}, 1724 1700 /* 8852B PCIE SCC */ 1725 1701 .wde_qt7 = {446, 48, 0, 16,}, 1702 + /* 8852C USB3.0 */ 1703 + .wde_qt16 = {344, 2, 0, 8,}, 1726 1704 /* 8852C DLFW */ 1727 1705 .wde_qt17 = {0, 0, 0, 0,}, 1728 1706 /* 8852C PCIE SCC */ ··· 1736 1702 .wde_qt23 = {958, 48, 0, 16,}, 1737 1703 /* 8852B USB2.0/USB3.0 SCC */ 1738 1704 .wde_qt25 = {152, 2, 0, 8,}, 1705 + /* 8852C USB2.0 */ 1706 + .wde_qt31 = {338, 6, 0, 40,}, 1739 1707 .ple_qt0 = {320, 320, 32, 16, 13, 13, 292, 292, 64, 18, 1, 4, 0,}, 1740 1708 .ple_qt1 = {320, 320, 32, 16, 1316, 1316, 1595, 1595, 1367, 1321, 1, 1307, 0,}, 1741 1709 /* PCIE SCC */ ··· 1749 1713 .ple_qt13 = {0, 0, 16, 48, 0, 0, 0, 0, 0, 0, 0,}, 1750 1714 /* PCIE 64 */ 1751 1715 .ple_qt18 = {147, 0, 16, 20, 17, 13, 89, 0, 32, 14, 8, 0,}, 1716 + /* 8852A USB SCC */ 1717 + .ple_qt25 = {1536, 0, 16, 48, 13, 13, 360, 0, 32, 40, 8, 0,}, 1718 + .ple_qt26 = {2654, 0, 1134, 48, 64, 13, 1478, 0, 64, 128, 120, 0,}, 1719 + /* USB 52C USB3.0 */ 1720 + .ple_qt42 = {1068, 0, 16, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,}, 1721 + /* USB 52C USB3.0 */ 1722 + .ple_qt43 = {3068, 0, 32, 48, 4, 13, 178, 0, 16, 1, 8, 16, 0,}, 1752 1723 /* DLFW 52C */ 1753 1724 .ple_qt44 = {0, 0, 16, 256, 0, 0, 0, 0, 0, 0, 0, 0,}, 1754 1725 /* DLFW 52C */ ··· 1775 1732 /* USB3.0 52B 92K */ 1776 1733 .ple_qt74 = {286, 0, 16, 48, 4, 13, 178, 0, 32, 14, 8, 0, 0,}, 1777 1734 .ple_qt75 = {286, 0, 32, 48, 37, 13, 211, 0, 65, 14, 24, 0, 0,}, 1735 + /* USB2.0 52C */ 1736 + .ple_qt78 = {1560, 0, 16, 48, 13, 13, 390, 0, 32, 38, 8, 16, 0,}, 1737 + /* USB2.0 52C */ 1738 + .ple_qt79 = {1560, 0, 32, 48, 1253, 13, 1630, 0, 1272, 38, 120, 1256, 0,}, 1778 1739 /* 8852A PCIE WOW */ 1779 1740 .ple_qt_52a_wow = {264, 0, 32, 20, 64, 13, 1005, 0, 64, 128, 120,}, 1780 1741 /* 8852B PCIE WOW */ ··· 2371 2324 if (chip->chip_id == RTL8852C) 2372 2325 val |= B_AX_UC_MGNT_DEC; 2373 2326 if (chip->chip_id == RTL8852A || chip->chip_id == RTL8852B || 2374 - chip->chip_id == RTL8851B) 2327 + chip->chip_id == RTL8851B || 2328 + (chip->chip_id == RTL8852C && rtwdev->hci.type == RTW89_HCI_TYPE_USB)) 2375 2329 val &= ~B_AX_TX_PARTIAL_MODE; 2376 2330 rtw89_write32(rtwdev, R_AX_SEC_ENG_CTRL, val); 2377 2331 ··· 2541 2493 rtw89_write32(rtwdev, reg, val); 2542 2494 2543 2495 return 0; 2496 + } 2497 + 2498 + void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr) 2499 + { 2500 + const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 2501 + u32 reg; 2502 + u32 val; 2503 + 2504 + reg = rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, mac_idx); 2505 + 2506 + val = rtw89_read32(rtwdev, reg); 2507 + /* B_AX_RX_FLTR_CFG_MASK is not a consecutive bit mask */ 2508 + val = (val & ~B_AX_RX_FLTR_CFG_MASK) | (rx_fltr & B_AX_RX_FLTR_CFG_MASK); 2509 + rtw89_write32(rtwdev, reg, val); 2544 2510 } 2545 2511 2546 2512 static int rx_fltr_init_ax(struct rtw89_dev *rtwdev, u8 mac_idx) ··· 4042 3980 4043 3981 val = rtw89_read32(rtwdev, R_AX_HAXI_INIT_CFG1); 4044 3982 val &= ~(B_AX_DMA_MODE_MASK | B_AX_STOP_AXI_MST); 4045 - val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B) | 4046 - B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1; 3983 + val |= B_AX_TXHCI_EN_V1 | B_AX_RXHCI_EN_V1; 3984 + 3985 + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) 3986 + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_PCIE_1B); 3987 + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) 3988 + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_USB); 3989 + else 3990 + val |= FIELD_PREP(B_AX_DMA_MODE_MASK, DMA_MOD_SDIO); 3991 + 4047 3992 rtw89_write32(rtwdev, R_AX_HAXI_INIT_CFG1, val); 4048 3993 4049 3994 rtw89_write32_clr(rtwdev, R_AX_HAXI_DMA_STOP1, ··· 4118 4049 rtw89_mac_ctrl_hci_dma_trx(rtwdev, true); 4119 4050 4120 4051 if (include_bb) { 4121 - rtw89_chip_bb_preinit(rtwdev, RTW89_PHY_0); 4122 - if (rtwdev->dbcc_en) 4123 - rtw89_chip_bb_preinit(rtwdev, RTW89_PHY_1); 4052 + /* Only call BB preinit including configuration of BB MCU for 4053 + * the chips which need to download BB MCU firmware. Otherwise, 4054 + * calling preinit later to prevent touching registers affecting 4055 + * download firmware. 4056 + */ 4057 + rtw89_chip_bb_preinit(rtwdev); 4124 4058 } 4125 4059 4126 4060 ret = rtw89_mac_dmac_pre_init(rtwdev); ··· 4143 4071 return 0; 4144 4072 } 4145 4073 4074 + int rtw89_mac_preinit(struct rtw89_dev *rtwdev) 4075 + { 4076 + int ret; 4077 + 4078 + ret = rtw89_mac_pwr_on(rtwdev); 4079 + if (ret) 4080 + return ret; 4081 + 4082 + return 0; 4083 + } 4084 + 4146 4085 int rtw89_mac_init(struct rtw89_dev *rtwdev) 4147 4086 { 4148 4087 const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 4149 4088 const struct rtw89_chip_info *chip = rtwdev->chip; 4150 4089 bool include_bb = !!chip->bbmcu_nr; 4151 4090 int ret; 4152 - 4153 - ret = rtw89_mac_pwr_on(rtwdev); 4154 - if (ret) 4155 - return ret; 4156 4091 4157 4092 ret = rtw89_mac_partial_init(rtwdev, include_bb); 4158 4093 if (ret) ··· 4849 4770 if (ret) 4850 4771 return ret; 4851 4772 4852 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); 4773 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_CREATE); 4853 4774 if (ret) 4854 4775 return ret; 4855 4776 ··· 4874 4795 4875 4796 rtw89_cam_deinit(rtwdev, rtwvif_link); 4876 4797 4877 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); 4798 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_REMOVE); 4878 4799 if (ret) 4879 4800 return ret; 4880 4801 ··· 5323 5244 } 5324 5245 5325 5246 static void 5326 - rtw89_mac_c2h_bcn_upd_done(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 5247 + rtw89_mac_c2h_bcn_upd_done(struct rtw89_dev *rtwdev, struct sk_buff *skb_c2h, u32 len) 5327 5248 { 5249 + const struct rtw89_c2h_bcn_upd_done *c2h = 5250 + (const struct rtw89_c2h_bcn_upd_done *)skb_c2h->data; 5251 + u8 band, port, mbssid; 5252 + 5253 + port = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_PORT); 5254 + mbssid = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_MBSSID); 5255 + band = le32_get_bits(c2h->w2, RTW89_C2H_BCN_UPD_DONE_W2_BAND_IDX); 5256 + 5257 + rtw89_debug(rtwdev, RTW89_DBG_FW, 5258 + "BCN update done on port:%d mbssid:%d band:%d\n", 5259 + port, mbssid, band); 5328 5260 } 5329 5261 5330 5262 static void ··· 5545 5455 data.err = err; 5546 5456 cond = RTW89_MCC_WAIT_COND(group, func); 5547 5457 rtw89_complete_cond(&rtwdev->mcc.wait, cond, &data); 5458 + } 5459 + 5460 + static void 5461 + rtw89_mac_c2h_tx_rpt(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) 5462 + { 5463 + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; 5464 + struct rtw89_tx_skb_data *skb_data; 5465 + u8 sw_define, tx_status, txcnt; 5466 + struct sk_buff *skb; 5467 + 5468 + if (rtwdev->chip->chip_id == RTL8922A) { 5469 + const struct rtw89_c2h_mac_tx_rpt_v2 *rpt_v2; 5470 + 5471 + rpt_v2 = (const struct rtw89_c2h_mac_tx_rpt_v2 *)c2h->data; 5472 + sw_define = le32_get_bits(rpt_v2->w12, 5473 + RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2); 5474 + tx_status = le32_get_bits(rpt_v2->w12, 5475 + RTW89_C2H_MAC_TX_RPT_W12_TX_STATE_V2); 5476 + txcnt = le32_get_bits(rpt_v2->w14, 5477 + RTW89_C2H_MAC_TX_RPT_W14_DATA_TX_CNT_V2); 5478 + } else { 5479 + const struct rtw89_c2h_mac_tx_rpt *rpt; 5480 + 5481 + rpt = (const struct rtw89_c2h_mac_tx_rpt *)c2h->data; 5482 + sw_define = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE); 5483 + tx_status = le32_get_bits(rpt->w2, RTW89_C2H_MAC_TX_RPT_W2_TX_STATE); 5484 + if (rtwdev->chip->chip_id == RTL8852C) 5485 + txcnt = le32_get_bits(rpt->w5, 5486 + RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT_V1); 5487 + else 5488 + txcnt = le32_get_bits(rpt->w5, 5489 + RTW89_C2H_MAC_TX_RPT_W5_DATA_TX_CNT); 5490 + } 5491 + 5492 + rtw89_debug(rtwdev, RTW89_DBG_TXRX, 5493 + "C2H TX RPT: sn %d, tx_status %d, txcnt %d\n", 5494 + sw_define, tx_status, txcnt); 5495 + 5496 + /* claim sw_define is not over size of tx_rpt->skbs[] */ 5497 + static_assert(hweight32(RTW89_MAX_TX_RPTS_MASK) == 5498 + hweight32(RTW89_C2H_MAC_TX_RPT_W12_SW_DEFINE_V2) && 5499 + hweight32(RTW89_MAX_TX_RPTS_MASK) == 5500 + hweight32(RTW89_C2H_MAC_TX_RPT_W2_SW_DEFINE)); 5501 + 5502 + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { 5503 + skb = tx_rpt->skbs[sw_define]; 5504 + 5505 + /* skip if no skb (normally shouldn't happen) */ 5506 + if (!skb) { 5507 + rtw89_debug(rtwdev, RTW89_DBG_TXRX, 5508 + "C2H TX RPT: no skb found in queue\n"); 5509 + return; 5510 + } 5511 + 5512 + skb_data = RTW89_TX_SKB_CB(skb); 5513 + 5514 + /* skip if TX attempt has failed and retry limit has not been 5515 + * reached yet 5516 + */ 5517 + if (tx_status != RTW89_TX_DONE && 5518 + txcnt != skb_data->tx_pkt_cnt_lmt) 5519 + return; 5520 + 5521 + tx_rpt->skbs[sw_define] = NULL; 5522 + rtw89_tx_rpt_tx_status(rtwdev, skb, tx_status); 5523 + } 5548 5524 } 5549 5525 5550 5526 static void ··· 5848 5692 }; 5849 5693 5850 5694 static 5695 + void (* const rtw89_mac_c2h_misc_handler[])(struct rtw89_dev *rtwdev, 5696 + struct sk_buff *c2h, u32 len) = { 5697 + [RTW89_MAC_C2H_FUNC_TX_REPORT] = rtw89_mac_c2h_tx_rpt, 5698 + }; 5699 + 5700 + static 5851 5701 void (* const rtw89_mac_c2h_mlo_handler[])(struct rtw89_dev *rtwdev, 5852 5702 struct sk_buff *c2h, u32 len) = { 5853 5703 [RTW89_MAC_C2H_FUNC_MLO_GET_TBL] = NULL, ··· 5939 5777 } 5940 5778 case RTW89_MAC_C2H_CLASS_MCC: 5941 5779 return true; 5780 + case RTW89_MAC_C2H_CLASS_MISC: 5781 + return true; 5942 5782 case RTW89_MAC_C2H_CLASS_MLO: 5943 5783 return true; 5944 5784 case RTW89_MAC_C2H_CLASS_MRC: ··· 5975 5811 case RTW89_MAC_C2H_CLASS_MCC: 5976 5812 if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MCC) 5977 5813 handler = rtw89_mac_c2h_mcc_handler[func]; 5814 + break; 5815 + case RTW89_MAC_C2H_CLASS_MISC: 5816 + if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MISC) 5817 + handler = rtw89_mac_c2h_misc_handler[func]; 5978 5818 break; 5979 5819 case RTW89_MAC_C2H_CLASS_MLO: 5980 5820 if (func < NUM_OF_RTW89_MAC_C2H_FUNC_MLO)
+112 -2
drivers/net/wireless/realtek/rtw89/mac.h
··· 432 432 NUM_OF_RTW89_MAC_C2H_FUNC_MCC, 433 433 }; 434 434 435 + enum rtw89_mac_c2h_misc_func { 436 + RTW89_MAC_C2H_FUNC_TX_REPORT = 1, 437 + 438 + NUM_OF_RTW89_MAC_C2H_FUNC_MISC, 439 + }; 440 + 435 441 enum rtw89_mac_c2h_mlo_func { 436 442 RTW89_MAC_C2H_FUNC_MLO_GET_TBL = 0x0, 437 443 RTW89_MAC_C2H_FUNC_MLO_EMLSR_TRANS_DONE = 0x1, ··· 476 470 RTW89_MAC_C2H_CLASS_WOW = 0x3, 477 471 RTW89_MAC_C2H_CLASS_MCC = 0x4, 478 472 RTW89_MAC_C2H_CLASS_FWDBG = 0x5, 473 + RTW89_MAC_C2H_CLASS_MISC = 0x9, 479 474 RTW89_MAC_C2H_CLASS_MLO = 0xc, 480 475 RTW89_MAC_C2H_CLASS_MRC = 0xe, 481 476 RTW89_MAC_C2H_CLASS_AP = 0x18, ··· 581 574 RTW89_MAC_BF_RRSC_MAX = 32 582 575 }; 583 576 584 - #define RTW89_R32_EA 0xEAEAEAEA 585 - #define RTW89_R32_DEAD 0xDEADBEEF 586 577 #define MAC_REG_POOL_COUNT 10 587 578 #define ACCESS_CMAC(_addr) \ 588 579 ({typeof(_addr) __addr = (_addr); \ ··· 922 917 const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c0; 923 918 const struct rtw89_hfc_prec_cfg hfc_prec_cfg_c2; 924 919 const struct rtw89_dle_size wde_size0; 920 + const struct rtw89_dle_size wde_size1; 925 921 const struct rtw89_dle_size wde_size0_v1; 926 922 const struct rtw89_dle_size wde_size4; 927 923 const struct rtw89_dle_size wde_size4_v1; 928 924 const struct rtw89_dle_size wde_size6; 929 925 const struct rtw89_dle_size wde_size7; 930 926 const struct rtw89_dle_size wde_size9; 927 + const struct rtw89_dle_size wde_size17; 931 928 const struct rtw89_dle_size wde_size18; 932 929 const struct rtw89_dle_size wde_size19; 933 930 const struct rtw89_dle_size wde_size23; 934 931 const struct rtw89_dle_size wde_size25; 932 + const struct rtw89_dle_size wde_size31; 935 933 const struct rtw89_dle_size ple_size0; 934 + const struct rtw89_dle_size ple_size1; 936 935 const struct rtw89_dle_size ple_size0_v1; 937 936 const struct rtw89_dle_size ple_size3_v1; 938 937 const struct rtw89_dle_size ple_size4; 939 938 const struct rtw89_dle_size ple_size6; 940 939 const struct rtw89_dle_size ple_size8; 941 940 const struct rtw89_dle_size ple_size9; 941 + const struct rtw89_dle_size ple_size17; 942 942 const struct rtw89_dle_size ple_size18; 943 943 const struct rtw89_dle_size ple_size19; 944 944 const struct rtw89_dle_size ple_size32; 945 945 const struct rtw89_dle_size ple_size33; 946 + const struct rtw89_dle_size ple_size34; 946 947 const struct rtw89_wde_quota wde_qt0; 948 + const struct rtw89_wde_quota wde_qt1; 947 949 const struct rtw89_wde_quota wde_qt0_v1; 948 950 const struct rtw89_wde_quota wde_qt4; 949 951 const struct rtw89_wde_quota wde_qt6; 950 952 const struct rtw89_wde_quota wde_qt7; 953 + const struct rtw89_wde_quota wde_qt16; 951 954 const struct rtw89_wde_quota wde_qt17; 952 955 const struct rtw89_wde_quota wde_qt18; 953 956 const struct rtw89_wde_quota wde_qt23; 954 957 const struct rtw89_wde_quota wde_qt25; 958 + const struct rtw89_wde_quota wde_qt31; 955 959 const struct rtw89_ple_quota ple_qt0; 956 960 const struct rtw89_ple_quota ple_qt1; 957 961 const struct rtw89_ple_quota ple_qt4; ··· 968 954 const struct rtw89_ple_quota ple_qt9; 969 955 const struct rtw89_ple_quota ple_qt13; 970 956 const struct rtw89_ple_quota ple_qt18; 957 + const struct rtw89_ple_quota ple_qt25; 958 + const struct rtw89_ple_quota ple_qt26; 959 + const struct rtw89_ple_quota ple_qt42; 960 + const struct rtw89_ple_quota ple_qt43; 971 961 const struct rtw89_ple_quota ple_qt44; 972 962 const struct rtw89_ple_quota ple_qt45; 973 963 const struct rtw89_ple_quota ple_qt46; ··· 983 965 const struct rtw89_ple_quota ple_qt73; 984 966 const struct rtw89_ple_quota ple_qt74; 985 967 const struct rtw89_ple_quota ple_qt75; 968 + const struct rtw89_ple_quota ple_qt78; 969 + const struct rtw89_ple_quota ple_qt79; 986 970 const struct rtw89_ple_quota ple_qt_52a_wow; 987 971 const struct rtw89_ple_quota ple_qt_52b_wow; 988 972 const struct rtw89_ple_quota ple_qt_52bt_wow; ··· 1201 1181 int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev); 1202 1182 void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev); 1203 1183 int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb); 1184 + int rtw89_mac_preinit(struct rtw89_dev *rtwdev); 1204 1185 int rtw89_mac_init(struct rtw89_dev *rtwdev); 1205 1186 int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode, 1206 1187 enum rtw89_qta_mode ext_mode); ··· 1340 1319 return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable); 1341 1320 } 1342 1321 1322 + void rtw89_mac_set_rx_fltr(struct rtw89_dev *rtwdev, u8 mac_idx, u32 rx_fltr); 1343 1323 void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev); 1344 1324 void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop); 1345 1325 int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex); ··· 1630 1608 } 1631 1609 1632 1610 return ret; 1611 + } 1612 + 1613 + static inline 1614 + void rtw89_tx_rpt_init(struct rtw89_dev *rtwdev, 1615 + struct rtw89_core_tx_request *tx_req) 1616 + { 1617 + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; 1618 + 1619 + if (!rtwdev->hci.tx_rpt_enabled) 1620 + return; 1621 + 1622 + tx_req->desc_info.report = true; 1623 + /* firmware maintains a 4-bit sequence number */ 1624 + tx_req->desc_info.sn = atomic_inc_return(&tx_rpt->sn) & 1625 + RTW89_MAX_TX_RPTS_MASK; 1626 + tx_req->desc_info.tx_cnt_lmt_en = true; 1627 + tx_req->desc_info.tx_cnt_lmt = 8; 1628 + } 1629 + 1630 + static inline 1631 + bool rtw89_is_tx_rpt_skb(struct rtw89_dev *rtwdev, struct sk_buff *skb) 1632 + { 1633 + struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); 1634 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1635 + 1636 + return rtw89_core_is_tx_wait(rtwdev, skb_data) || 1637 + (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS); 1638 + } 1639 + 1640 + static inline 1641 + void rtw89_tx_rpt_tx_status(struct rtw89_dev *rtwdev, struct sk_buff *skb, 1642 + u8 tx_status) 1643 + { 1644 + struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); 1645 + struct ieee80211_tx_info *info; 1646 + 1647 + if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status)) 1648 + return; 1649 + 1650 + info = IEEE80211_SKB_CB(skb); 1651 + ieee80211_tx_info_clear_status(info); 1652 + 1653 + if (tx_status == RTW89_TX_DONE) 1654 + info->flags |= IEEE80211_TX_STAT_ACK; 1655 + else 1656 + info->flags &= ~IEEE80211_TX_STAT_ACK; 1657 + 1658 + ieee80211_tx_status_irqsafe(rtwdev->hw, skb); 1659 + } 1660 + 1661 + static inline 1662 + void rtw89_tx_rpt_skb_add(struct rtw89_dev *rtwdev, struct sk_buff *skb) 1663 + { 1664 + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; 1665 + struct rtw89_tx_skb_data *skb_data; 1666 + u8 idx; 1667 + 1668 + skb_data = RTW89_TX_SKB_CB(skb); 1669 + idx = skb_data->tx_rpt_sn; 1670 + 1671 + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { 1672 + /* if skb having the similar seq number is still in the queue, 1673 + * this means the queue is overflowed - it isn't normal and 1674 + * should indicate firmware doesn't provide TX reports in time; 1675 + * report the old skb as dropped, we can't do much more here 1676 + */ 1677 + if (tx_rpt->skbs[idx]) 1678 + rtw89_tx_rpt_tx_status(rtwdev, tx_rpt->skbs[idx], 1679 + RTW89_TX_MACID_DROP); 1680 + tx_rpt->skbs[idx] = skb; 1681 + } 1682 + } 1683 + 1684 + static inline 1685 + void rtw89_tx_rpt_skbs_purge(struct rtw89_dev *rtwdev) 1686 + { 1687 + struct rtw89_tx_rpt *tx_rpt = &rtwdev->tx_rpt; 1688 + struct sk_buff *skbs[RTW89_MAX_TX_RPTS]; 1689 + 1690 + scoped_guard(spinlock_irqsave, &tx_rpt->skb_lock) { 1691 + memcpy(skbs, tx_rpt->skbs, sizeof(tx_rpt->skbs)); 1692 + memset(tx_rpt->skbs, 0, sizeof(tx_rpt->skbs)); 1693 + } 1694 + 1695 + for (int i = 0; i < ARRAY_SIZE(skbs); i++) 1696 + if (skbs[i]) 1697 + rtw89_tx_rpt_tx_status(rtwdev, skbs[i], 1698 + RTW89_TX_MACID_DROP); 1633 1699 } 1634 1700 #endif
+77 -12
drivers/net/wireless/realtek/rtw89/mac80211.c
··· 220 220 if (ret) 221 221 goto unset_link; 222 222 223 + rtwdev->pure_monitor_mode_vif = vif->type == NL80211_IFTYPE_MONITOR ? 224 + rtwvif : NULL; 223 225 rtw89_recalc_lps(rtwdev); 224 226 return 0; 225 227 ··· 269 267 rtw89_core_release_bit_map(rtwdev->hw_port, port); 270 268 rtw89_release_mac_id(rtwdev, macid); 271 269 270 + rtwdev->pure_monitor_mode_vif = NULL; 271 + 272 272 rtw89_recalc_lps(rtwdev); 273 273 rtw89_enter_ips_by_hwflags(rtwdev); 274 274 } ··· 307 303 u64 multicast) 308 304 { 309 305 struct rtw89_dev *rtwdev = hw->priv; 310 - const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; 311 306 u32 rx_fltr; 312 307 313 308 lockdep_assert_wiphy(hw->wiphy); ··· 368 365 rx_fltr &= ~B_AX_A_A1_MATCH; 369 366 } 370 367 371 - rtw89_write32_mask(rtwdev, 372 - rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_0), 373 - B_AX_RX_FLTR_CFG_MASK, 374 - rx_fltr); 368 + rtw89_mac_set_rx_fltr(rtwdev, RTW89_MAC_0, rx_fltr); 375 369 if (!rtwdev->dbcc_en) 376 370 return; 377 - rtw89_write32_mask(rtwdev, 378 - rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1), 379 - B_AX_RX_FLTR_CFG_MASK, 380 - rx_fltr); 371 + rtw89_mac_set_rx_fltr(rtwdev, RTW89_MAC_1, rx_fltr); 381 372 } 382 373 383 374 static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = { ··· 715 718 716 719 if (changed & BSS_CHANGED_ARP_FILTER) 717 720 rtwvif->ip_addr = vif->cfg.arp_addr_list[0]; 721 + 722 + if (changed & BSS_CHANGED_MLD_VALID_LINKS) { 723 + struct rtw89_vif_link *cur = rtw89_get_designated_link(rtwvif); 724 + 725 + rtw89_chip_rfk_channel(rtwdev, cur); 726 + 727 + if (hweight16(vif->active_links) == 1) 728 + rtwvif->mlo_mode = RTW89_MLO_MODE_MLSR; 729 + else 730 + rtwvif->mlo_mode = RTW89_MLO_MODE_EMLSR; 731 + } 718 732 } 719 733 720 734 static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw, ··· 752 744 if (changed & BSS_CHANGED_BSSID) { 753 745 ether_addr_copy(rtwvif_link->bssid, conf->bssid); 754 746 rtw89_cam_bssid_changed(rtwdev, rtwvif_link); 755 - rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); 747 + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_INFO_CHANGE); 756 748 WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0); 757 749 } 758 750 ··· 811 803 rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL); 812 804 rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE); 813 805 rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true); 814 - rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL); 806 + rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL, RTW89_ROLE_TYPE_CHANGE); 815 807 rtw89_chip_rfk_channel(rtwdev, rtwvif_link); 816 808 817 809 if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) { ··· 962 954 } 963 955 break; 964 956 case DISABLE_KEY: 957 + flush_work(&rtwdev->txq_work); 965 958 rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, 966 959 false); 967 960 rtw89_mac_flush_txq(rtwdev, BIT(rtwdev->hw->queues) - 1, false); ··· 1141 1132 { 1142 1133 struct rtw89_dev *rtwdev = hw->priv; 1143 1134 struct rtw89_hal *hal = &rtwdev->hal; 1135 + const struct rtw89_chip_info *chip; 1144 1136 1145 1137 lockdep_assert_wiphy(hw->wiphy); 1138 + 1139 + chip = rtwdev->chip; 1146 1140 1147 1141 if (hal->ant_diversity) { 1148 1142 if (tx_ant != rx_ant || hweight32(tx_ant) != 1) 1149 1143 return -EINVAL; 1144 + } else if (chip->ops->cfg_txrx_path) { 1145 + /* With cfg_txrx_path ops, chips can configure rx_ant */ 1150 1146 } else if (rx_ant != hw->wiphy->available_antennas_rx && rx_ant != hal->antenna_rx) { 1151 1147 return -EINVAL; 1152 1148 } ··· 1545 1531 u16 active_links) 1546 1532 { 1547 1533 struct rtw89_dev *rtwdev = hw->priv; 1534 + struct rtw89_vif *rtwvif = vif_to_rtwvif(vif); 1535 + u16 current_links = vif->active_links; 1536 + struct rtw89_vif_ml_trans trans = { 1537 + .mediate_links = current_links | active_links, 1538 + .links_to_del = current_links & ~active_links, 1539 + .links_to_add = active_links & ~current_links, 1540 + }; 1548 1541 1549 1542 lockdep_assert_wiphy(hw->wiphy); 1550 1543 1551 - return rtw89_can_work_on_links(rtwdev, vif, active_links); 1544 + if (!rtw89_can_work_on_links(rtwdev, vif, active_links)) 1545 + return false; 1546 + 1547 + /* 1548 + * Leave LPS at the beginning of ieee80211_set_active_links(). 1549 + * Because the entire process takes the same lock as our track 1550 + * work, LPS will not enter during ieee80211_set_active_links(). 1551 + */ 1552 + rtw89_leave_lps(rtwdev); 1553 + 1554 + rtwvif->ml_trans = trans; 1555 + 1556 + return true; 1552 1557 } 1553 1558 1554 1559 static void __rtw89_ops_clr_vif_links(struct rtw89_dev *rtwdev, ··· 1612 1579 return 0; 1613 1580 } 1614 1581 1582 + static void rtw89_vif_cfg_fw_links(struct rtw89_dev *rtwdev, 1583 + struct rtw89_vif *rtwvif, 1584 + unsigned long links, bool en) 1585 + { 1586 + struct rtw89_vif_link *rtwvif_link; 1587 + unsigned int link_id; 1588 + 1589 + for_each_set_bit(link_id, &links, IEEE80211_MLD_MAX_NUM_LINKS) { 1590 + rtwvif_link = rtwvif->links[link_id]; 1591 + if (unlikely(!rtwvif_link)) 1592 + continue; 1593 + 1594 + rtw89_fw_h2c_mlo_link_cfg(rtwdev, rtwvif_link, en); 1595 + } 1596 + } 1597 + 1598 + static void rtw89_vif_update_fw_links(struct rtw89_dev *rtwdev, 1599 + struct rtw89_vif *rtwvif, 1600 + u16 current_links) 1601 + { 1602 + struct rtw89_vif_ml_trans *trans = &rtwvif->ml_trans; 1603 + 1604 + /* Do follow-up when all updating links exist. */ 1605 + if (current_links != trans->mediate_links) 1606 + return; 1607 + 1608 + rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_del, false); 1609 + rtw89_vif_cfg_fw_links(rtwdev, rtwvif, trans->links_to_add, true); 1610 + } 1611 + 1615 1612 static 1616 1613 int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, 1617 1614 struct ieee80211_vif *vif, ··· 1682 1619 1683 1620 if (rtwdev->scanning) 1684 1621 rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); 1622 + 1623 + rtw89_vif_update_fw_links(rtwdev, rtwvif, old_links); 1685 1624 1686 1625 if (!old_links) 1687 1626 __rtw89_ops_clr_vif_links(rtwdev, rtwvif,
+8 -1
drivers/net/wireless/realtek/rtw89/mac_be.c
··· 458 458 459 459 static int wcpu_on(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) 460 460 { 461 + const struct rtw89_chip_info *chip = rtwdev->chip; 461 462 u32 val32; 462 463 int ret; 463 464 ··· 480 479 481 480 rtw89_write32(rtwdev, R_BE_UDM1, 0); 482 481 rtw89_write32(rtwdev, R_BE_UDM2, 0); 482 + rtw89_write32(rtwdev, R_BE_BOOT_DBG, 0x0); 483 483 rtw89_write32(rtwdev, R_BE_HALT_H2C, 0); 484 484 rtw89_write32(rtwdev, R_BE_HALT_C2H, 0); 485 485 rtw89_write32(rtwdev, R_BE_HALT_H2C_CTRL, 0); ··· 495 493 B_BE_WDT_WAKE_PCIE_EN | B_BE_WDT_WAKE_USB_EN); 496 494 rtw89_write32_clr(rtwdev, R_BE_WCPU_FW_CTRL, 497 495 B_BE_WDT_PLT_RST_EN | B_BE_WCPU_ROM_CUT_GET); 496 + rtw89_write32(rtwdev, R_BE_SECURE_BOOT_MALLOC_INFO, 0); 497 + rtw89_write32_clr(rtwdev, R_BE_GPIO_MUXCFG, B_BE_BOOT_MODE); 498 + 499 + if (chip->chip_id != RTL8922A) 500 + rtw89_write32_set(rtwdev, R_BE_WCPU_FW_CTRL, B_BE_HOST_EXIST); 498 501 499 502 rtw89_write16_mask(rtwdev, R_BE_BOOT_REASON, B_BE_BOOT_REASON_MASK, boot_reason); 500 503 rtw89_write32_clr(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_WCPU_EN); ··· 2027 2020 } 2028 2021 2029 2022 rtw89_write32_mask(rtwdev, R_BE_HW_PPDU_STATUS, B_BE_FWD_PPDU_STAT_MASK, 3); 2030 - rtw89_write32(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN | B_BE_PPDU_MAC_INFO | 2023 + rtw89_write32(rtwdev, reg, B_BE_PPDU_STAT_RPT_EN | 2031 2024 B_BE_APP_RX_CNT_RPT | B_BE_APP_PLCP_HDR_RPT | 2032 2025 B_BE_PPDU_STAT_RPT_CRC32 | B_BE_PPDU_STAT_RPT_DMA); 2033 2026
+17 -1
drivers/net/wireless/realtek/rtw89/pci.c
··· 464 464 struct rtw89_tx_skb_data *skb_data = RTW89_TX_SKB_CB(skb); 465 465 struct ieee80211_tx_info *info; 466 466 467 - if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status == RTW89_TX_DONE)) 467 + if (rtw89_core_tx_wait_complete(rtwdev, skb_data, tx_status)) 468 468 return; 469 469 470 470 info = IEEE80211_SKB_CB(skb); ··· 2062 2062 struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; 2063 2063 2064 2064 writel(data, rtwpci->mmap + addr); 2065 + } 2066 + 2067 + static u32 rtw89_pci_ops_read32_pci_cfg(struct rtw89_dev *rtwdev, u32 addr) 2068 + { 2069 + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; 2070 + struct pci_dev *pdev = rtwpci->pdev; 2071 + u32 value; 2072 + int ret; 2073 + 2074 + ret = pci_read_config_dword(pdev, addr, &value); 2075 + if (ret) 2076 + return RTW89_R32_EA; 2077 + 2078 + return value; 2065 2079 } 2066 2080 2067 2081 static void rtw89_pci_ctrl_dma_trx(struct rtw89_dev *rtwdev, bool enable) ··· 4696 4682 .write8 = rtw89_pci_ops_write8, 4697 4683 .write16 = rtw89_pci_ops_write16, 4698 4684 .write32 = rtw89_pci_ops_write32, 4685 + 4686 + .read32_pci_cfg = rtw89_pci_ops_read32_pci_cfg, 4699 4687 4700 4688 .mac_pre_init = rtw89_pci_ops_mac_pre_init, 4701 4689 .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit,
-4
drivers/net/wireless/realtek/rtw89/pci.h
··· 1487 1487 #define RTW89_PCI_RPP_POLLUTED BIT(31) 1488 1488 #define RTW89_PCI_RPP_SEQ GENMASK(30, 16) 1489 1489 #define RTW89_PCI_RPP_TX_STATUS GENMASK(15, 13) 1490 - #define RTW89_TX_DONE 0x0 1491 - #define RTW89_TX_RETRY_LIMIT 0x1 1492 - #define RTW89_TX_LIFE_TIME 0x2 1493 - #define RTW89_TX_MACID_DROP 0x3 1494 1490 #define RTW89_PCI_RPP_QSEL GENMASK(12, 8) 1495 1491 #define RTW89_PCI_RPP_MACID GENMASK(7, 0) 1496 1492
+63 -2
drivers/net/wireless/realtek/rtw89/phy.c
··· 231 231 return -1; 232 232 } 233 233 234 - if (link_sta->he_cap.has_he) { 234 + if (link_sta->eht_cap.has_eht) { 235 + cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[0], 236 + RA_MASK_EHT_1SS_RATES); 237 + cfg_mask |= u64_encode_bits(mask->control[band].eht_mcs[1], 238 + RA_MASK_EHT_2SS_RATES); 239 + } else if (link_sta->he_cap.has_he) { 235 240 cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[0], 236 241 RA_MASK_HE_1SS_RATES); 237 242 cfg_mask |= u64_encode_bits(mask->control[band].he_mcs[1], ··· 476 471 ra->ra_mask = ra_mask; 477 472 ra->fix_giltf_en = fix_giltf_en; 478 473 ra->fix_giltf = fix_giltf; 474 + ra->partial_bw_er = link_sta->he_cap.has_he ? 475 + !!(link_sta->he_cap.he_cap_elem.phy_cap_info[6] & 476 + IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE) : 0; 477 + ra->band = chan->band_type; 479 478 480 479 if (!csi) 481 480 return; ··· 566 557 return true; 567 558 } 568 559 560 + enum __rtw89_hw_rate_invalid_bases { 561 + /* no EHT rate for ax chip */ 562 + RTW89_HW_RATE_EHT_NSS1_MCS0 = RTW89_HW_RATE_INVAL, 563 + RTW89_HW_RATE_EHT_NSS2_MCS0 = RTW89_HW_RATE_INVAL, 564 + RTW89_HW_RATE_EHT_NSS3_MCS0 = RTW89_HW_RATE_INVAL, 565 + RTW89_HW_RATE_EHT_NSS4_MCS0 = RTW89_HW_RATE_INVAL, 566 + }; 567 + 569 568 #define RTW89_HW_RATE_BY_CHIP_GEN(rate) \ 570 569 { \ 571 570 [RTW89_CHIP_AX] = RTW89_HW_RATE_ ## rate, \ ··· 589 572 struct rtw89_phy_rate_pattern next_pattern = {0}; 590 573 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, 591 574 rtwvif_link->chanctx_idx); 575 + static const u16 hw_rate_eht[][RTW89_CHIP_GEN_NUM] = { 576 + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS1_MCS0), 577 + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS2_MCS0), 578 + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS3_MCS0), 579 + RTW89_HW_RATE_BY_CHIP_GEN(EHT_NSS4_MCS0), 580 + }; 592 581 static const u16 hw_rate_he[][RTW89_CHIP_GEN_NUM] = { 593 582 RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS1_MCS0), 594 583 RTW89_HW_RATE_BY_CHIP_GEN(HE_NSS2_MCS0), ··· 619 596 u8 tx_nss = rtwdev->hal.tx_nss; 620 597 u8 i; 621 598 599 + if (chip_gen == RTW89_CHIP_AX) 600 + goto rs_11ax; 601 + 602 + for (i = 0; i < tx_nss; i++) 603 + if (!__check_rate_pattern(&next_pattern, hw_rate_eht[i][chip_gen], 604 + RA_MASK_EHT_RATES, RTW89_RA_MODE_EHT, 605 + mask->control[nl_band].eht_mcs[i], 606 + 0, true)) 607 + goto out; 608 + 609 + rs_11ax: 622 610 for (i = 0; i < tx_nss; i++) 623 611 if (!__check_rate_pattern(&next_pattern, hw_rate_he[i][chip_gen], 624 612 RA_MASK_HE_RATES, RTW89_RA_MODE_HE, ··· 673 639 674 640 if (!next_pattern.enable) 675 641 goto out; 642 + 643 + if (unlikely(next_pattern.rate >= RTW89_HW_RATE_INVAL)) { 644 + rtw89_debug(rtwdev, RTW89_DBG_RA, 645 + "pattern invalid target: chip_gen %d, mode 0x%x\n", 646 + chip_gen, next_pattern.ra_mode); 647 + goto out; 648 + } 676 649 677 650 rtwvif_link->rate_pattern = next_pattern; 678 651 rtw89_debug(rtwdev, RTW89_DBG_RA, ··· 2380 2339 } 2381 2340 } 2382 2341 2342 + static bool rtw89_phy_validate_txpwr_limit_bw(struct rtw89_dev *rtwdev, 2343 + u8 band, u8 bw) 2344 + { 2345 + switch (band) { 2346 + case RTW89_BAND_2G: 2347 + return bw < RTW89_2G_BW_NUM; 2348 + case RTW89_BAND_5G: 2349 + return bw < RTW89_5G_BW_NUM; 2350 + case RTW89_BAND_6G: 2351 + return bw < RTW89_6G_BW_NUM; 2352 + default: 2353 + return false; 2354 + } 2355 + } 2356 + 2383 2357 s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band, 2384 2358 u8 bw, u8 ntx, u8 rs, u8 bf, u8 ch) 2385 2359 { ··· 2418 2362 .ntx = ntx, 2419 2363 }; 2420 2364 s8 cstr; 2365 + 2366 + if (!rtw89_phy_validate_txpwr_limit_bw(rtwdev, band, bw)) { 2367 + rtw89_warn(rtwdev, "invalid band %u bandwidth %u\n", band, bw); 2368 + return 0; 2369 + } 2421 2370 2422 2371 switch (band) { 2423 2372 case RTW89_BAND_2G: ··· 4612 4551 s32 dcfo_comp_val; 4613 4552 int sign; 4614 4553 4615 - if (rtwdev->chip->chip_id == RTL8922A) 4554 + if (!dcfo_comp) 4616 4555 return; 4617 4556 4618 4557 if (!is_linked) {
+4
drivers/net/wireless/realtek/rtw89/phy_be.c
··· 266 266 case 3: 267 267 rtw89_phy_cfg_bb_gain_op1db_be(rtwdev, arg, reg->data); 268 268 break; 269 + case 15: 270 + rtw89_phy_write32_idx(rtwdev, reg->addr & 0xFFFFF, MASKHWORD, 271 + reg->data, RTW89_PHY_0); 272 + break; 269 273 case 4: 270 274 /* This cfg_type is only used by rfe_type >= 50 with eFEM */ 271 275 if (efuse->rfe_type < 50)
+21 -2
drivers/net/wireless/realtek/rtw89/ps.c
··· 11 11 #include "phy.h" 12 12 #include "ps.h" 13 13 #include "reg.h" 14 + #include "ser.h" 14 15 #include "util.h" 15 16 16 17 static int rtw89_fw_receive_lps_h2c_check(struct rtw89_dev *rtwdev, u8 macid) ··· 27 26 c2h_info.id = RTW89_FWCMD_C2HREG_FUNC_PS_LEAVE_ACK; 28 27 ret = rtw89_fw_msg_reg(rtwdev, NULL, &c2h_info); 29 28 if (ret) 30 - return ret; 29 + goto fw_fail; 31 30 32 31 c2hreg_macid = u32_get_bits(c2h_info.u.c2hreg[0], 33 32 RTW89_C2HREG_PS_LEAVE_ACK_MACID); 34 33 c2hreg_ret = u32_get_bits(c2h_info.u.c2hreg[1], RTW89_C2HREG_PS_LEAVE_ACK_RET); 35 34 36 - if (macid != c2hreg_macid || c2hreg_ret) 35 + if (macid != c2hreg_macid || c2hreg_ret) { 37 36 rtw89_warn(rtwdev, "rtw89: check lps h2c received by firmware fail\n"); 37 + ret = -EINVAL; 38 + goto fw_fail; 39 + } 40 + rtwdev->ps_hang_cnt = 0; 38 41 39 42 return 0; 43 + 44 + fw_fail: 45 + rtwdev->ps_hang_cnt++; 46 + if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT) 47 + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); 48 + 49 + return ret; 40 50 } 41 51 42 52 static int rtw89_fw_leave_lps_check(struct rtw89_dev *rtwdev, u8 macid) ··· 63 51 mac->ps_status, chk_msk); 64 52 if (ret) { 65 53 rtw89_info(rtwdev, "rtw89: failed to leave lps state\n"); 54 + 55 + rtwdev->ps_hang_cnt++; 56 + if (rtwdev->ps_hang_cnt >= RTW89_PS_HANG_MAX_CNT) 57 + rtw89_ser_notify(rtwdev, MAC_AX_ERR_ASSERTION); 58 + 66 59 return -EBUSY; 67 60 } 61 + 62 + rtwdev->ps_hang_cnt = 0; 68 63 69 64 return 0; 70 65 }
+23 -1
drivers/net/wireless/realtek/rtw89/reg.h
··· 3963 3963 #define R_BE_EFUSE_CTRL_1_V1 0x0034 3964 3964 #define B_BE_EF_DATA_MASK GENMASK(31, 0) 3965 3965 3966 + #define R_BE_GPIO_MUXCFG 0x0040 3967 + #define B_BE_WCPU_AUTO_EN BIT(26) 3968 + #define B_BE_WCPU_JTAG_EN BIT(24) 3969 + #define B_BE_WCPU_DBG_EN BIT(23) 3970 + #define B_BE_JTAG_CHAIN_EN BIT(20) 3971 + #define B_BE_BOOT_MODE BIT(19) 3972 + #define B_BE_WL_EECS_EXT_32K_SEL BIT(18) 3973 + #define B_BE_WL_SEC_BONDING_OPT_STS BIT(17) 3974 + #define B_BE_SECSIC_SEL BIT(16) 3975 + #define B_BE_ENHTP BIT(14) 3976 + #define B_BE_ENSIC BIT(12) 3977 + #define B_BE_SIC_SWRST BIT(11) 3978 + #define B_BE_PINMUX_PTA_EN BIT(10) 3979 + #define B_BE_WL_BT_PTA_SEC BIT(9) 3980 + #define B_BE_ENUARTTX BIT(8) 3981 + #define B_BE_DBG_GNT_BT_S1_POLARITY BIT(4) 3982 + #define B_BE_ENUARTRX BIT(2) 3983 + 3966 3984 #define R_BE_GPIO_EXT_CTRL 0x0060 3967 3985 #define B_BE_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24) 3968 3986 #define B_BE_GPIO_MOD_9 BIT(25) ··· 4341 4323 #define B_BE_RUN_ENV_MASK GENMASK(31, 30) 4342 4324 #define B_BE_WCPU_FWDL_STATUS_MASK GENMASK(29, 26) 4343 4325 #define B_BE_WDT_PLT_RST_EN BIT(17) 4326 + #define B_BE_HOST_EXIST BIT(16) 4344 4327 #define B_BE_FW_SEC_AUTH_DONE BIT(14) 4345 4328 #define B_BE_FW_CPU_UTIL_STS_EN BIT(13) 4346 4329 #define B_BE_BBMCU1_FWDL_EN BIT(12) ··· 4617 4598 #define B_BE_HCI_TRXBUF_EN BIT(2) 4618 4599 #define B_BE_HCI_RXDMA_EN BIT(1) 4619 4600 #define B_BE_HCI_TXDMA_EN BIT(0) 4601 + 4602 + #define R_BE_BOOT_DBG 0x78F0 4603 + #define B_BE_BOOT_STATUS_MASK GENMASK(31, 16) 4604 + #define B_BE_SECUREBOOT_STATUS_MASK GENMASK(15, 0) 4620 4605 4621 4606 #define R_BE_DBG_WOW_READY 0x815E 4622 4607 #define B_BE_DBG_WOW_READY GENMASK(7, 0) ··· 7499 7476 #define B_BE_PPDU_STAT_RPT_ADDR BIT(4) 7500 7477 #define B_BE_APP_PLCP_HDR_RPT BIT(3) 7501 7478 #define B_BE_APP_RX_CNT_RPT BIT(2) 7502 - #define B_BE_PPDU_MAC_INFO BIT(1) 7503 7479 #define B_BE_PPDU_STAT_RPT_EN BIT(0) 7504 7480 7505 7481 #define R_BE_RX_SR_CTRL 0x1144A
+11 -11
drivers/net/wireless/realtek/rtw89/regd.c
··· 723 723 chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code); 724 724 if (!rtw89_regd_is_ww(chip_regd)) { 725 725 rtwdev->regulatory.regd = chip_regd; 726 + rtwdev->regulatory.programmed = true; 727 + 726 728 /* Ignore country ie if there is a country domain programmed in chip */ 727 729 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; 728 730 wiphy->regulatory_flags |= REGULATORY_STRICT_REG; ··· 869 867 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE; 870 868 else 871 869 wiphy->regulatory_flags &= ~REGULATORY_COUNTRY_IE_IGNORE; 872 - 873 - rtw89_regd_apply_policy_unii4(rtwdev, wiphy); 874 - rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); 875 - rtw89_regd_apply_policy_tas(rtwdev); 876 - rtw89_regd_apply_policy_ant_gain(rtwdev); 877 870 } 878 871 879 872 static ··· 880 883 wiphy_lock(wiphy); 881 884 rtw89_leave_ps_mode(rtwdev); 882 885 883 - if (wiphy->regd) { 884 - rtw89_debug(rtwdev, RTW89_DBG_REGD, 885 - "There is a country domain programmed in chip, ignore notifications\n"); 886 - goto exit; 887 - } 886 + if (rtwdev->regulatory.programmed) 887 + goto policy; 888 + 888 889 rtw89_regd_notifier_apply(rtwdev, wiphy, request); 889 890 rtw89_debug_regd(rtwdev, rtwdev->regulatory.regd, 890 891 "get from initiator %d, alpha2", 891 892 request->initiator); 892 893 894 + policy: 895 + rtw89_regd_apply_policy_unii4(rtwdev, wiphy); 896 + rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); 897 + rtw89_regd_apply_policy_tas(rtwdev); 898 + rtw89_regd_apply_policy_ant_gain(rtwdev); 899 + 893 900 rtw89_core_set_chip_txpwr(rtwdev); 894 901 895 - exit: 896 902 wiphy_unlock(wiphy); 897 903 } 898 904
+4 -1
drivers/net/wireless/realtek/rtw89/rtw8851b.c
··· 2537 2537 .query_rxdesc = rtw89_core_query_rxdesc, 2538 2538 .fill_txdesc = rtw89_core_fill_txdesc, 2539 2539 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, 2540 - .get_ch_dma = rtw89_core_get_ch_dma, 2540 + .get_ch_dma = {rtw89_core_get_ch_dma, 2541 + rtw89_core_get_ch_dma, 2542 + NULL,}, 2541 2543 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, 2542 2544 .mac_cfg_gnt = rtw89_mac_cfg_gnt, 2543 2545 .stop_sch_tx = rtw89_mac_stop_sch_tx, ··· 2648 2646 .bacam_num = 2, 2649 2647 .bacam_dynamic_num = 4, 2650 2648 .bacam_ver = RTW89_BACAM_V0, 2649 + .addrcam_ver = 0, 2651 2650 .ppdu_max_usr = 4, 2652 2651 .sec_ctrl_efuse_size = 4, 2653 2652 .physical_efuse_size = 1216,
+4 -4
drivers/net/wireless/realtek/rtw89/rtw8851b_rfk.c
··· 1626 1626 iqk_info->iqk_table_idx[path] = idx; 1627 1627 1628 1628 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", 1629 - path, phy, rtwdev->dbcc_en ? "on" : "off", 1629 + path, phy, str_on_off(rtwdev->dbcc_en), 1630 1630 iqk_info->iqk_band[path] == 0 ? "2G" : 1631 1631 iqk_info->iqk_band[path] == 1 ? "5G" : "6G", 1632 1632 iqk_info->iqk_ch[path], ··· 1901 1901 rtw89_debug(rtwdev, RTW89_DBG_RFK, 1902 1902 "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", 1903 1903 path, dpk->cur_idx[path], phy, 1904 - rtwdev->is_tssi_mode[path] ? "on" : "off", 1905 - rtwdev->dbcc_en ? "on" : "off", 1904 + str_on_off(rtwdev->is_tssi_mode[path]), 1905 + str_on_off(rtwdev->dbcc_en), 1906 1906 dpk->bp[path][kidx].band == 0 ? "2G" : 1907 1907 dpk->bp[path][kidx].band == 1 ? "5G" : "6G", 1908 1908 dpk->bp[path][kidx].ch, ··· 2016 2016 rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); 2017 2017 2018 2018 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", 2019 - path, force ? "on" : "off"); 2019 + path, str_on_off(force)); 2020 2020 } 2021 2021 2022 2022 static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on)
+24
drivers/net/wireless/realtek/rtw89/rtw8851bu.c
··· 5 5 #include <linux/module.h> 6 6 #include <linux/usb.h> 7 7 #include "rtw8851b.h" 8 + #include "reg.h" 8 9 #include "usb.h" 10 + 11 + static const struct rtw89_usb_info rtw8851b_usb_info = { 12 + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2, 13 + .usb_wlan0_1 = R_AX_USB_WLAN0_1, 14 + .hci_func_en = R_AX_HCI_FUNC_EN, 15 + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0, 16 + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0, 17 + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2, 18 + .bulkout_id = { 19 + [RTW89_DMA_ACH0] = 3, 20 + [RTW89_DMA_ACH1] = 4, 21 + [RTW89_DMA_ACH2] = 5, 22 + [RTW89_DMA_ACH3] = 6, 23 + [RTW89_DMA_B0MG] = 0, 24 + [RTW89_DMA_B0HI] = 1, 25 + [RTW89_DMA_H2C] = 2, 26 + }, 27 + }; 9 28 10 29 static const struct rtw89_driver_info rtw89_8851bu_info = { 11 30 .chip = &rtw8851b_chip_info, 12 31 .variant = NULL, 13 32 .quirks = NULL, 33 + .bus = { 34 + .usb = &rtw8851b_usb_info, 35 + } 14 36 }; 15 37 16 38 static const struct usb_device_id rtw_8851bu_id_table[] = { 39 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb831, 0xff, 0xff, 0xff), 40 + .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, 17 41 { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xb851, 0xff, 0xff, 0xff), 18 42 .driver_info = (kernel_ulong_t)&rtw89_8851bu_info }, 19 43 /* D-Link AX9U rev. A1 */
+73 -12
drivers/net/wireless/realtek/rtw89/rtw8852a.c
··· 48 48 [RTW89_QTA_INVALID] = {NULL}, 49 49 }; 50 50 51 + static const struct rtw89_hfc_ch_cfg rtw8852a_hfc_chcfg_usb[] = { 52 + {22, 402, grp_0}, /* ACH 0 */ 53 + {0, 0, grp_0}, /* ACH 1 */ 54 + {22, 402, grp_0}, /* ACH 2 */ 55 + {0, 0, grp_0}, /* ACH 3 */ 56 + {22, 402, grp_0}, /* ACH 4 */ 57 + {0, 0, grp_0}, /* ACH 5 */ 58 + {22, 402, grp_0}, /* ACH 6 */ 59 + {0, 0, grp_0}, /* ACH 7 */ 60 + {22, 402, grp_0}, /* B0MGQ */ 61 + {0, 0, grp_0}, /* B0HIQ */ 62 + {22, 402, grp_0}, /* B1MGQ */ 63 + {0, 0, grp_0}, /* B1HIQ */ 64 + {0, 0, 0} /* FWCMDQ */ 65 + }; 66 + 67 + static const struct rtw89_hfc_pub_cfg rtw8852a_hfc_pubcfg_usb = { 68 + 512, /* Group 0 */ 69 + 0, /* Group 1 */ 70 + 512, /* Public Max */ 71 + 104 /* WP threshold */ 72 + }; 73 + 74 + static const struct rtw89_hfc_prec_cfg rtw8852a_hfc_preccfg_usb = { 75 + 11, /* CH 0-11 pre-cost */ 76 + 32, /* H2C pre-cost */ 77 + 76, /* WP CH 0-7 pre-cost */ 78 + 25, /* WP CH 8-11 pre-cost */ 79 + 1, /* CH 0-11 full condition */ 80 + 1, /* H2C full condition */ 81 + 1, /* WP CH 0-7 full condition */ 82 + 1, /* WP CH 8-11 full condition */ 83 + }; 84 + 85 + static const struct rtw89_hfc_param_ini rtw8852a_hfc_param_ini_usb[] = { 86 + [RTW89_QTA_SCC] = {rtw8852a_hfc_chcfg_usb, &rtw8852a_hfc_pubcfg_usb, 87 + &rtw8852a_hfc_preccfg_usb, RTW89_HCIFC_STF}, 88 + [RTW89_QTA_DLFW] = {NULL, NULL, 89 + &rtw8852a_hfc_preccfg_usb, RTW89_HCIFC_STF}, 90 + [RTW89_QTA_INVALID] = {NULL}, 91 + }; 92 + 51 93 static const struct rtw89_dle_mem rtw8852a_dle_mem_pcie[] = { 52 94 [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0, 53 95 &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, ··· 99 57 &rtw89_mac_size.ple_size0, &rtw89_mac_size.wde_qt0, 100 58 &rtw89_mac_size.wde_qt0, &rtw89_mac_size.ple_qt4, 101 59 &rtw89_mac_size.ple_qt_52a_wow}, 60 + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, 61 + &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, 62 + &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, 63 + &rtw89_mac_size.ple_qt13}, 64 + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, 65 + NULL}, 66 + }; 67 + 68 + static const struct rtw89_dle_mem rtw8852a_dle_mem_usb[] = { 69 + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size1, 70 + &rtw89_mac_size.ple_size1, &rtw89_mac_size.wde_qt1, 71 + &rtw89_mac_size.wde_qt1, &rtw89_mac_size.ple_qt25, 72 + &rtw89_mac_size.ple_qt26}, 102 73 [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4, 103 74 &rtw89_mac_size.ple_size4, &rtw89_mac_size.wde_qt4, 104 75 &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt13, ··· 621 566 .tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M, 622 567 }; 623 568 624 - static void rtw8852ae_efuse_parsing(struct rtw89_efuse *efuse, 625 - struct rtw8852a_efuse *map) 626 - { 627 - ether_addr_copy(efuse->addr, map->e.mac_addr); 628 - efuse->rfe_type = map->rfe_type; 629 - efuse->xtal_cap = map->xtal_k; 630 - } 631 - 632 569 static void rtw8852a_efuse_parsing_tssi(struct rtw89_dev *rtwdev, 633 570 struct rtw8852a_efuse *map) 634 571 { ··· 666 619 667 620 switch (rtwdev->hci.type) { 668 621 case RTW89_HCI_TYPE_PCIE: 669 - rtw8852ae_efuse_parsing(efuse, map); 622 + ether_addr_copy(efuse->addr, map->e.mac_addr); 623 + break; 624 + case RTW89_HCI_TYPE_USB: 625 + ether_addr_copy(efuse->addr, map->u.mac_addr); 670 626 break; 671 627 default: 672 628 return -ENOTSUPP; 673 629 } 630 + 631 + efuse->rfe_type = map->rfe_type; 632 + efuse->xtal_cap = map->xtal_k; 674 633 675 634 rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); 676 635 ··· 2231 2178 .query_rxdesc = rtw89_core_query_rxdesc, 2232 2179 .fill_txdesc = rtw89_core_fill_txdesc, 2233 2180 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, 2234 - .get_ch_dma = rtw89_core_get_ch_dma, 2181 + .get_ch_dma = {rtw89_core_get_ch_dma, 2182 + rtw89_core_get_ch_dma_v2, 2183 + NULL,}, 2235 2184 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, 2236 2185 .mac_cfg_gnt = rtw89_mac_cfg_gnt, 2237 2186 .stop_sch_tx = rtw89_mac_stop_sch_tx, ··· 2277 2222 .max_amsdu_limit = 3500, 2278 2223 .dis_2g_40m_ul_ofdma = true, 2279 2224 .rsvd_ple_ofst = 0x6f800, 2280 - .hfc_param_ini = {rtw8852a_hfc_param_ini_pcie, NULL, NULL}, 2281 - .dle_mem = {rtw8852a_dle_mem_pcie, NULL, NULL, NULL}, 2225 + .hfc_param_ini = {rtw8852a_hfc_param_ini_pcie, 2226 + rtw8852a_hfc_param_ini_usb, 2227 + NULL}, 2228 + .dle_mem = {rtw8852a_dle_mem_pcie, 2229 + rtw8852a_dle_mem_usb, 2230 + rtw8852a_dle_mem_usb, 2231 + NULL}, 2282 2232 .wde_qempty_acq_grpnum = 16, 2283 2233 .wde_qempty_mgq_grpsel = 16, 2284 2234 .rf_base_addr = {0xc000, 0xd000}, ··· 2334 2274 .bacam_num = 2, 2335 2275 .bacam_dynamic_num = 4, 2336 2276 .bacam_ver = RTW89_BACAM_V0, 2277 + .addrcam_ver = 0, 2337 2278 .ppdu_max_usr = 4, 2338 2279 .sec_ctrl_efuse_size = 4, 2339 2280 .physical_efuse_size = 1216,
+8 -8
drivers/net/wireless/realtek/rtw89/rtw8852a_rfk.c
··· 756 756 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); 757 757 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x0); 758 758 udelay(1); 759 - rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); 760 - rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); 759 + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); 760 + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000); 761 761 762 762 switch (iqk_info->iqk_band[path]) { 763 763 case RTW89_BAND_2G: ··· 1239 1239 udelay(1); 1240 1240 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); 1241 1241 udelay(1); 1242 - rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); 1243 - rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); 1242 + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0303); 1243 + rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0000); 1244 1244 switch (iqk_info->iqk_band[path]) { 1245 1245 case RTW89_BAND_2G: 1246 1246 rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW, 0x00); ··· 1403 1403 path, iqk_info->iqk_ch[path]); 1404 1404 rtw89_debug(rtwdev, RTW89_DBG_RFK, 1405 1405 "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, 1406 - rtwdev->dbcc_en ? "on" : "off", 1406 + str_on_off(rtwdev->dbcc_en), 1407 1407 iqk_info->iqk_band[path] == 0 ? "2G" : 1408 1408 iqk_info->iqk_band[path] == 1 ? "5G" : "6G", 1409 1409 iqk_info->iqk_ch[path], ··· 1881 1881 rtw89_debug(rtwdev, RTW89_DBG_RFK, 1882 1882 "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", 1883 1883 path, dpk->cur_idx[path], phy, 1884 - rtwdev->is_tssi_mode[path] ? "on" : "off", 1885 - rtwdev->dbcc_en ? "on" : "off", 1884 + str_on_off(rtwdev->is_tssi_mode[path]), 1885 + str_on_off(rtwdev->dbcc_en), 1886 1886 dpk->bp[path][kidx].band == 0 ? "2G" : 1887 1887 dpk->bp[path][kidx].band == 1 ? "5G" : "6G", 1888 1888 dpk->bp[path][kidx].ch, ··· 2736 2736 MASKBYTE3, 0x6 | val); 2737 2737 2738 2738 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, 2739 - kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); 2739 + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); 2740 2740 } 2741 2741 2742 2742 static void _dpk_track(struct rtw89_dev *rtwdev)
+79
drivers/net/wireless/realtek/rtw89/rtw8852au.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* Copyright(c) 2025 Realtek Corporation 3 + */ 4 + 5 + #include <linux/module.h> 6 + #include <linux/usb.h> 7 + #include "rtw8852a.h" 8 + #include "reg.h" 9 + #include "usb.h" 10 + 11 + static const struct rtw89_usb_info rtw8852a_usb_info = { 12 + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2, 13 + .usb_wlan0_1 = R_AX_USB_WLAN0_1, 14 + .hci_func_en = R_AX_HCI_FUNC_EN, 15 + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0, 16 + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0, 17 + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2, 18 + .bulkout_id = { 19 + [RTW89_DMA_ACH0] = 3, 20 + [RTW89_DMA_ACH2] = 5, 21 + [RTW89_DMA_ACH4] = 4, 22 + [RTW89_DMA_ACH6] = 6, 23 + [RTW89_DMA_B0MG] = 0, 24 + [RTW89_DMA_B0HI] = 0, 25 + [RTW89_DMA_B1MG] = 1, 26 + [RTW89_DMA_B1HI] = 1, 27 + [RTW89_DMA_H2C] = 2, 28 + }, 29 + }; 30 + 31 + static const struct rtw89_driver_info rtw89_8852au_info = { 32 + .chip = &rtw8852a_chip_info, 33 + .variant = NULL, 34 + .quirks = NULL, 35 + .bus = { 36 + .usb = &rtw8852a_usb_info, 37 + } 38 + }; 39 + 40 + static const struct usb_device_id rtw_8852au_id_table[] = { 41 + { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0312, 0xff, 0xff, 0xff), 42 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 43 + { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4020, 0xff, 0xff, 0xff), 44 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 45 + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1997, 0xff, 0xff, 0xff), 46 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 47 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x8832, 0xff, 0xff, 0xff), 48 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 49 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885a, 0xff, 0xff, 0xff), 50 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 51 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0x885c, 0xff, 0xff, 0xff), 52 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 53 + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3321, 0xff, 0xff, 0xff), 54 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 55 + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x332c, 0xff, 0xff, 0xff), 56 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 57 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x013f, 0xff, 0xff, 0xff), 58 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 59 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0140, 0xff, 0xff, 0xff), 60 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 61 + { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0141, 0xff, 0xff, 0xff), 62 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 63 + { USB_DEVICE_AND_INTERFACE_INFO(0x3625, 0x010f, 0xff, 0xff, 0xff), 64 + .driver_info = (kernel_ulong_t)&rtw89_8852au_info }, 65 + {}, 66 + }; 67 + MODULE_DEVICE_TABLE(usb, rtw_8852au_id_table); 68 + 69 + static struct usb_driver rtw_8852au_driver = { 70 + .name = KBUILD_MODNAME, 71 + .id_table = rtw_8852au_id_table, 72 + .probe = rtw89_usb_probe, 73 + .disconnect = rtw89_usb_disconnect, 74 + }; 75 + module_usb_driver(rtw_8852au_driver); 76 + 77 + MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>"); 78 + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852AU driver"); 79 + MODULE_LICENSE("Dual BSD/GPL");
+4 -1
drivers/net/wireless/realtek/rtw89/rtw8852b.c
··· 842 842 .query_rxdesc = rtw89_core_query_rxdesc, 843 843 .fill_txdesc = rtw89_core_fill_txdesc, 844 844 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, 845 - .get_ch_dma = rtw89_core_get_ch_dma, 845 + .get_ch_dma = {rtw89_core_get_ch_dma, 846 + rtw89_core_get_ch_dma, 847 + NULL,}, 846 848 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, 847 849 .mac_cfg_gnt = rtw89_mac_cfg_gnt, 848 850 .stop_sch_tx = rtw89_mac_stop_sch_tx, ··· 959 957 .bacam_num = 2, 960 958 .bacam_dynamic_num = 4, 961 959 .bacam_ver = RTW89_BACAM_V0, 960 + .addrcam_ver = 0, 962 961 .ppdu_max_usr = 4, 963 962 .sec_ctrl_efuse_size = 4, 964 963 .physical_efuse_size = 1216,
+5 -1
drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
··· 1747 1747 struct rtw89_hal *hal = &rtwdev->hal; 1748 1748 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); 1749 1749 enum rtw89_rf_path_bit rx_path = hal->antenna_rx ? hal->antenna_rx : RF_AB; 1750 + u8 rx_nss = rtwdev->hal.rx_nss; 1751 + 1752 + if (rx_path != RF_AB) 1753 + rx_nss = 1; 1750 1754 1751 1755 rtw8852bx_bb_ctrl_rx_path(rtwdev, rx_path, chan); 1752 1756 rtw8852bx_bb_ctrl_rf_mode_rx_path(rtwdev, rx_path); 1753 1757 1754 - if (rtwdev->hal.rx_nss == 1) { 1758 + if (rx_nss == 1) { 1755 1759 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); 1756 1760 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); 1757 1761 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0);
+3 -3
drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c
··· 1696 1696 MASKBYTE3, _dpk_order_convert(rtwdev) << 1 | val); 1697 1697 1698 1698 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, 1699 - kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); 1699 + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); 1700 1700 } 1701 1701 1702 1702 static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ··· 1763 1763 rtw89_debug(rtwdev, RTW89_DBG_RFK, 1764 1764 "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", 1765 1765 path, dpk->cur_idx[path], phy, 1766 - rtwdev->is_tssi_mode[path] ? "on" : "off", 1767 - rtwdev->dbcc_en ? "on" : "off", 1766 + str_on_off(rtwdev->is_tssi_mode[path]), 1767 + str_on_off(rtwdev->dbcc_en), 1768 1768 dpk->bp[path][kidx].band == 0 ? "2G" : 1769 1769 dpk->bp[path][kidx].band == 1 ? "5G" : "6G", 1770 1770 dpk->bp[path][kidx].ch,
+4 -1
drivers/net/wireless/realtek/rtw89/rtw8852bt.c
··· 708 708 .query_rxdesc = rtw89_core_query_rxdesc, 709 709 .fill_txdesc = rtw89_core_fill_txdesc, 710 710 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc, 711 - .get_ch_dma = rtw89_core_get_ch_dma, 711 + .get_ch_dma = {rtw89_core_get_ch_dma, 712 + NULL, 713 + NULL,}, 712 714 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path, 713 715 .mac_cfg_gnt = rtw89_mac_cfg_gnt, 714 716 .stop_sch_tx = rtw89_mac_stop_sch_tx, ··· 818 816 .bacam_num = 2, 819 817 .bacam_dynamic_num = 4, 820 818 .bacam_ver = RTW89_BACAM_V0, 819 + .addrcam_ver = 0, 821 820 .ppdu_max_usr = 4, 822 821 .sec_ctrl_efuse_size = 4, 823 822 .physical_efuse_size = 1216,
+24
drivers/net/wireless/realtek/rtw89/rtw8852bu.c
··· 5 5 #include <linux/module.h> 6 6 #include <linux/usb.h> 7 7 #include "rtw8852b.h" 8 + #include "reg.h" 8 9 #include "usb.h" 10 + 11 + static const struct rtw89_usb_info rtw8852b_usb_info = { 12 + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2, 13 + .usb_wlan0_1 = R_AX_USB_WLAN0_1, 14 + .hci_func_en = R_AX_HCI_FUNC_EN, 15 + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0, 16 + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0, 17 + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2, 18 + .bulkout_id = { 19 + [RTW89_DMA_ACH0] = 3, 20 + [RTW89_DMA_ACH1] = 4, 21 + [RTW89_DMA_ACH2] = 5, 22 + [RTW89_DMA_ACH3] = 6, 23 + [RTW89_DMA_B0MG] = 0, 24 + [RTW89_DMA_B0HI] = 1, 25 + [RTW89_DMA_H2C] = 2, 26 + }, 27 + }; 9 28 10 29 static const struct rtw89_driver_info rtw89_8852bu_info = { 11 30 .chip = &rtw8852b_chip_info, 12 31 .variant = NULL, 13 32 .quirks = NULL, 33 + .bus = { 34 + .usb = &rtw8852b_usb_info, 35 + } 14 36 }; 15 37 16 38 static const struct usb_device_id rtw_8852bu_id_table[] = { ··· 49 27 { USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3428, 0xff, 0xff, 0xff), 50 28 .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, 51 29 { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1a62, 0xff, 0xff, 0xff), 30 + .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, 31 + { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x1cb6, 0xff, 0xff, 0xff), 52 32 .driver_info = (kernel_ulong_t)&rtw89_8852bu_info }, 53 33 { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x6931, 0xff, 0xff, 0xff), 54 34 .driver_info = (kernel_ulong_t)&rtw89_8852bu_info },
+144 -26
drivers/net/wireless/realtek/rtw89/rtw8852c.c
··· 51 51 [RTW89_QTA_INVALID] = {NULL}, 52 52 }; 53 53 54 + static const struct rtw89_hfc_ch_cfg rtw8852c_hfc_chcfg_usb[] = { 55 + {18, 344, grp_0}, /* ACH 0 */ 56 + {0, 0, grp_0}, /* ACH 1 */ 57 + {18, 344, grp_0}, /* ACH 2 */ 58 + {0, 0, grp_0}, /* ACH 3 */ 59 + {18, 344, grp_0}, /* ACH 4 */ 60 + {0, 0, grp_0}, /* ACH 5 */ 61 + {18, 344, grp_0}, /* ACH 6 */ 62 + {0, 0, grp_0}, /* ACH 7 */ 63 + {18, 344, grp_0}, /* B0MGQ */ 64 + {0, 0, grp_0}, /* B0HIQ */ 65 + {18, 344, grp_0}, /* B1MGQ */ 66 + {0, 0, grp_0}, /* B1HIQ */ 67 + {0, 0, 0} /* FWCMDQ */ 68 + }; 69 + 70 + static const struct rtw89_hfc_pub_cfg rtw8852c_hfc_pubcfg_usb = { 71 + 344, /* Group 0 */ 72 + 0, /* Group 1 */ 73 + 344, /* Public Max */ 74 + 0 /* WP threshold */ 75 + }; 76 + 77 + static const struct rtw89_hfc_prec_cfg rtw8852c_hfc_preccfg_usb = { 78 + 9, /* CH 0-11 pre-cost */ 79 + 32, /* H2C pre-cost */ 80 + 146, /* WP CH 0-7 pre-cost */ 81 + 146, /* WP CH 8-11 pre-cost */ 82 + 1, /* CH 0-11 full condition */ 83 + 1, /* H2C full condition */ 84 + 1, /* WP CH 0-7 full condition */ 85 + 1, /* WP CH 8-11 full condition */ 86 + }; 87 + 88 + static const struct rtw89_hfc_param_ini rtw8852c_hfc_param_ini_usb[] = { 89 + [RTW89_QTA_SCC] = {rtw8852c_hfc_chcfg_usb, &rtw8852c_hfc_pubcfg_usb, 90 + &rtw8852c_hfc_preccfg_usb, RTW89_HCIFC_STF}, 91 + [RTW89_QTA_DLFW] = {NULL, NULL, 92 + &rtw8852c_hfc_preccfg_usb, RTW89_HCIFC_STF}, 93 + [RTW89_QTA_INVALID] = {NULL}, 94 + }; 95 + 54 96 static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = { 55 97 [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19, 56 98 &rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18, 57 99 &rtw89_mac_size.wde_qt18, &rtw89_mac_size.ple_qt46, 58 100 &rtw89_mac_size.ple_qt47}, 101 + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, 102 + &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, 103 + &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, 104 + &rtw89_mac_size.ple_qt45}, 105 + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, 106 + NULL}, 107 + }; 108 + 109 + static const struct rtw89_dle_mem rtw8852c_dle_mem_usb2[] = { 110 + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size31, 111 + &rtw89_mac_size.ple_size34, &rtw89_mac_size.wde_qt31, 112 + &rtw89_mac_size.wde_qt31, &rtw89_mac_size.ple_qt78, 113 + &rtw89_mac_size.ple_qt79}, 114 + [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, 115 + &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, 116 + &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, 117 + &rtw89_mac_size.ple_qt45}, 118 + [RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL, 119 + NULL}, 120 + }; 121 + 122 + static const struct rtw89_dle_mem rtw8852c_dle_mem_usb3[] = { 123 + [RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size17, 124 + &rtw89_mac_size.ple_size17, &rtw89_mac_size.wde_qt16, 125 + &rtw89_mac_size.wde_qt16, &rtw89_mac_size.ple_qt42, 126 + &rtw89_mac_size.ple_qt43}, 59 127 [RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18, 60 128 &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17, 61 129 &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44, ··· 282 214 int ret; 283 215 284 216 val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK); 285 - if (val32 == MAC_AX_HCI_SEL_PCIE_USB) 217 + if (val32 == MAC_AX_HCI_SEL_PCIE_USB || 218 + rtwdev->hci.type == RTW89_HCI_TYPE_USB) 286 219 rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L); 287 220 288 221 rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN | ··· 315 246 rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); 316 247 317 248 rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN); 318 - rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); 249 + 250 + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) 251 + rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1); 319 252 320 253 rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN); 321 254 rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP); ··· 376 305 377 306 rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14); 378 307 rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK); 379 - rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN, 380 - B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN | 381 - B_AX_LED1_PULL_LOW_EN); 308 + 309 + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) 310 + rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN, 311 + B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN | 312 + B_AX_LED1_PULL_LOW_EN); 382 313 383 314 rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN, 384 315 B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN | ··· 458 385 if (ret) 459 386 return ret; 460 387 461 - rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); 388 + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) 389 + rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, SW_LPS_OPTION); 390 + else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) 391 + rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_SOP_EDSWR); 392 + 462 393 rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE); 463 394 rtw89_write32_set(rtwdev, R_AX_SYS_SWR_CTRL1, B_AX_SYM_CTRL_SPS_PWMFREQ); 464 395 rtw89_write32_mask(rtwdev, R_AX_SPS_DIG_ON_CTRL0, 465 396 B_AX_REG_ZCDC_H_MASK, 0x3); 466 - rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); 397 + 398 + if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE) { 399 + rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS); 400 + } else if (rtwdev->hci.type == RTW89_HCI_TYPE_USB) { 401 + val32 = rtw89_read32(rtwdev, R_AX_SYS_PW_CTRL); 402 + val32 &= ~B_AX_AFSM_PCIE_SUS_EN; 403 + val32 |= B_AX_AFSM_WLSUS_EN; 404 + rtw89_write32(rtwdev, R_AX_SYS_PW_CTRL, val32); 405 + } 467 406 468 407 return 0; 469 - } 470 - 471 - static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse, 472 - struct rtw8852c_efuse *map) 473 - { 474 - ether_addr_copy(efuse->addr, map->e.mac_addr); 475 - efuse->rfe_type = map->rfe_type; 476 - efuse->xtal_cap = map->xtal_k; 477 408 } 478 409 479 410 static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev, ··· 588 511 589 512 switch (rtwdev->hci.type) { 590 513 case RTW89_HCI_TYPE_PCIE: 591 - rtw8852c_e_efuse_parsing(efuse, map); 514 + ether_addr_copy(efuse->addr, map->e.mac_addr); 515 + break; 516 + case RTW89_HCI_TYPE_USB: 517 + ether_addr_copy(efuse->addr, map->u.mac_addr); 592 518 break; 593 519 default: 594 520 return -ENOTSUPP; 595 521 } 522 + 523 + efuse->rfe_type = map->rfe_type; 524 + efuse->xtal_cap = map->xtal_k; 596 525 597 526 rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type); 598 527 ··· 670 587 } 671 588 } 672 589 590 + #define __THM_MASK_SIGN BIT(0) 591 + #define __THM_MASK_3BITS GENMASK(3, 1) 592 + #define __THM_MASK_VAL8 BIT(4) 593 + 673 594 static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev) 674 595 { 675 - #define __thm_setting(raw) \ 676 - ({ \ 677 - u8 __v = (raw); \ 678 - ((__v & 0x1) << 3) | ((__v & 0x1f) >> 1); \ 596 + #define __thm_setting(raw) \ 597 + ({ \ 598 + u8 __v = (raw); \ 599 + ((__v & __THM_MASK_SIGN) << 3) | ((__v & __THM_MASK_3BITS) >> 1); \ 679 600 }) 680 601 struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; 681 602 u8 i, val; ··· 2502 2415 static void rtw8852c_bb_cfg_txrx_path(struct rtw89_dev *rtwdev) 2503 2416 { 2504 2417 struct rtw89_hal *hal = &rtwdev->hal; 2418 + u8 nrx_path = RF_PATH_AB; 2419 + u8 rx_nss = hal->rx_nss; 2505 2420 2506 - rtw8852c_bb_cfg_rx_path(rtwdev, RF_PATH_AB); 2421 + if (hal->antenna_rx == RF_A) 2422 + nrx_path = RF_PATH_A; 2423 + else if (hal->antenna_rx == RF_B) 2424 + nrx_path = RF_PATH_B; 2507 2425 2508 - if (hal->rx_nss == 1) { 2426 + if (nrx_path != RF_PATH_AB) 2427 + rx_nss = 1; 2428 + 2429 + rtw8852c_bb_cfg_rx_path(rtwdev, nrx_path); 2430 + 2431 + if (rx_nss == 1) { 2509 2432 rtw89_phy_write32_mask(rtwdev, R_RXHT_MCS_LIMIT, B_RXHT_MCS_LIMIT, 0); 2510 2433 rtw89_phy_write32_mask(rtwdev, R_RXVHT_MCS_LIMIT, B_RXVHT_MCS_LIMIT, 0); 2511 2434 rtw89_phy_write32_mask(rtwdev, R_RXHE, B_RXHE_MAX_NSS, 0); ··· 2530 2433 2531 2434 static u8 rtw8852c_get_thermal(struct rtw89_dev *rtwdev, enum rtw89_rf_path rf_path) 2532 2435 { 2436 + struct rtw89_power_trim_info *info = &rtwdev->pwr_trim; 2437 + s8 comp = 0; 2438 + u8 val; 2439 + 2533 2440 rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); 2534 2441 rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x0); 2535 2442 rtw89_write_rf(rtwdev, rf_path, RR_TM, RR_TM_TRI, 0x1); 2536 2443 2537 2444 fsleep(200); 2538 2445 2539 - return rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); 2446 + val = rtw89_read_rf(rtwdev, rf_path, RR_TM, RR_TM_VAL); 2447 + 2448 + if (info->pg_thermal_trim) { 2449 + u8 trim = info->thermal_trim[rf_path]; 2450 + 2451 + if (trim & __THM_MASK_VAL8) 2452 + comp = 8 * (trim & __THM_MASK_SIGN ? -1 : 1); 2453 + } 2454 + 2455 + return val + comp; 2540 2456 } 2541 2457 2542 2458 static void rtw8852c_btc_set_rfe(struct rtw89_dev *rtwdev) ··· 3072 2962 .query_rxdesc = rtw89_core_query_rxdesc, 3073 2963 .fill_txdesc = rtw89_core_fill_txdesc_v1, 3074 2964 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v1, 3075 - .get_ch_dma = rtw89_core_get_ch_dma, 2965 + .get_ch_dma = {rtw89_core_get_ch_dma, 2966 + rtw89_core_get_ch_dma_v2, 2967 + NULL,}, 3076 2968 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v1, 3077 2969 .mac_cfg_gnt = rtw89_mac_cfg_gnt_v1, 3078 2970 .stop_sch_tx = rtw89_mac_stop_sch_tx_v1, ··· 3118 3006 .max_amsdu_limit = 8000, 3119 3007 .dis_2g_40m_ul_ofdma = false, 3120 3008 .rsvd_ple_ofst = 0x6f800, 3121 - .hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, NULL, NULL}, 3122 - .dle_mem = {rtw8852c_dle_mem_pcie, NULL, NULL, NULL}, 3009 + .hfc_param_ini = {rtw8852c_hfc_param_ini_pcie, 3010 + rtw8852c_hfc_param_ini_usb, 3011 + NULL}, 3012 + .dle_mem = {rtw8852c_dle_mem_pcie, 3013 + rtw8852c_dle_mem_usb2, 3014 + rtw8852c_dle_mem_usb3, 3015 + NULL}, 3123 3016 .wde_qempty_acq_grpnum = 16, 3124 3017 .wde_qempty_mgq_grpsel = 16, 3125 3018 .rf_base_addr = {0xe000, 0xf000}, ··· 3178 3061 .bacam_num = 8, 3179 3062 .bacam_dynamic_num = 8, 3180 3063 .bacam_ver = RTW89_BACAM_V0_EXT, 3064 + .addrcam_ver = 0, 3181 3065 .ppdu_max_usr = 8, 3182 3066 .sec_ctrl_efuse_size = 4, 3183 3067 .physical_efuse_size = 1216,
+1 -1
drivers/net/wireless/realtek/rtw89/rtw8852c.h
··· 11 11 #define BB_PATH_NUM_8852C 2 12 12 13 13 struct rtw8852c_u_efuse { 14 - u8 rsvd[0x38]; 14 + u8 rsvd[0x88]; 15 15 u8 mac_addr[ETH_ALEN]; 16 16 }; 17 17
+44 -25
drivers/net/wireless/realtek/rtw89/rtw8852c_rfk.c
··· 1344 1344 path, iqk_info->iqk_ch[path]); 1345 1345 rtw89_debug(rtwdev, RTW89_DBG_RFK, 1346 1346 "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, 1347 - rtwdev->dbcc_en ? "on" : "off", 1347 + str_on_off(rtwdev->dbcc_en), 1348 1348 iqk_info->iqk_band[path] == 0 ? "2G" : 1349 1349 iqk_info->iqk_band[path] == 1 ? "5G" : "6G", 1350 1350 iqk_info->iqk_ch[path], ··· 1920 1920 rtw89_debug(rtwdev, RTW89_DBG_RFK, 1921 1921 "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", 1922 1922 path, dpk->cur_idx[path], phy, 1923 - rtwdev->is_tssi_mode[path] ? "on" : "off", 1924 - rtwdev->dbcc_en ? "on" : "off", 1923 + str_on_off(rtwdev->is_tssi_mode[path]), 1924 + str_on_off(rtwdev->dbcc_en), 1925 1925 dpk->bp[path][kidx].band == 0 ? "2G" : 1926 1926 dpk->bp[path][kidx].band == 1 ? "5G" : "6G", 1927 1927 dpk->bp[path][kidx].ch, ··· 2000 2000 rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); 2001 2001 2002 2002 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", 2003 - path, force ? "on" : "off"); 2003 + path, str_on_off(force)); 2004 2004 } 2005 2005 2006 2006 static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, ··· 2828 2828 B_DPD_MEN, val); 2829 2829 2830 2830 rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, 2831 - kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); 2831 + kidx, str_enable_disable(dpk->is_dpk_enable && !off)); 2832 2832 } 2833 2833 2834 2834 static void _dpk_track(struct rtw89_dev *rtwdev) ··· 3987 3987 } 3988 3988 } 3989 3989 3990 + static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 3991 + enum rtw89_bandwidth bw) 3992 + { 3993 + u32 val; 3994 + 3995 + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); 3996 + rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa); 3997 + 3998 + switch (bw) { 3999 + case RTW89_CHANNEL_WIDTH_20: 4000 + val = 0x1b; 4001 + break; 4002 + case RTW89_CHANNEL_WIDTH_40: 4003 + val = 0x13; 4004 + break; 4005 + case RTW89_CHANNEL_WIDTH_80: 4006 + val = 0xb; 4007 + break; 4008 + case RTW89_CHANNEL_WIDTH_160: 4009 + default: 4010 + val = 0x3; 4011 + break; 4012 + } 4013 + 4014 + rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val); 4015 + rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); 4016 + } 4017 + 4018 + static void _set_tia_bw(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 4019 + enum rtw89_bandwidth bw) 4020 + { 4021 + if (bw == RTW89_CHANNEL_WIDTH_160) 4022 + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); 4023 + else 4024 + rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x2); 4025 + } 4026 + 3990 4027 static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3991 4028 enum rtw89_bandwidth bw) 3992 4029 { 3993 4030 u8 kpath; 3994 4031 u8 path; 3995 - u32 val; 3996 4032 3997 4033 kpath = _kpath(rtwdev, phy); 3998 4034 for (path = 0; path < 2; path++) { 3999 4035 if (!(kpath & BIT(path))) 4000 4036 continue; 4001 4037 4002 - rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); 4003 - rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0xa); 4004 - switch (bw) { 4005 - case RTW89_CHANNEL_WIDTH_20: 4006 - val = 0x1b; 4007 - break; 4008 - case RTW89_CHANNEL_WIDTH_40: 4009 - val = 0x13; 4010 - break; 4011 - case RTW89_CHANNEL_WIDTH_80: 4012 - val = 0xb; 4013 - break; 4014 - case RTW89_CHANNEL_WIDTH_160: 4015 - default: 4016 - val = 0x3; 4017 - break; 4018 - } 4019 - rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, val); 4020 - rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); 4038 + _set_rxbb_bw(rtwdev, path, bw); 4039 + _set_tia_bw(rtwdev, path, bw); 4021 4040 } 4022 4041 } 4023 4042
+69
drivers/net/wireless/realtek/rtw89/rtw8852cu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 + /* Copyright(c) 2025 Realtek Corporation 3 + */ 4 + 5 + #include <linux/module.h> 6 + #include <linux/usb.h> 7 + #include "rtw8852c.h" 8 + #include "reg.h" 9 + #include "usb.h" 10 + 11 + static const struct rtw89_usb_info rtw8852c_usb_info = { 12 + .usb_host_request_2 = R_AX_USB_HOST_REQUEST_2_V1, 13 + .usb_wlan0_1 = R_AX_USB_WLAN0_1_V1, 14 + .hci_func_en = R_AX_HCI_FUNC_EN_V1, 15 + .usb3_mac_npi_config_intf_0 = R_AX_USB3_MAC_NPI_CONFIG_INTF_0_V1, 16 + .usb_endpoint_0 = R_AX_USB_ENDPOINT_0_V1, 17 + .usb_endpoint_2 = R_AX_USB_ENDPOINT_2_V1, 18 + .bulkout_id = { 19 + [RTW89_DMA_ACH0] = 3, 20 + [RTW89_DMA_ACH2] = 5, 21 + [RTW89_DMA_ACH4] = 4, 22 + [RTW89_DMA_ACH6] = 6, 23 + [RTW89_DMA_B0MG] = 0, 24 + [RTW89_DMA_B0HI] = 0, 25 + [RTW89_DMA_B1MG] = 1, 26 + [RTW89_DMA_B1HI] = 1, 27 + [RTW89_DMA_H2C] = 2, 28 + }, 29 + }; 30 + 31 + static const struct rtw89_driver_info rtw89_8852cu_info = { 32 + .chip = &rtw8852c_chip_info, 33 + .variant = NULL, 34 + .quirks = NULL, 35 + .bus = { 36 + .usb = &rtw8852c_usb_info, 37 + }, 38 + }; 39 + 40 + static const struct usb_device_id rtw_8852cu_id_table[] = { 41 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc832, 0xff, 0xff, 0xff), 42 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 43 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85a, 0xff, 0xff, 0xff), 44 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 45 + { USB_DEVICE_AND_INTERFACE_INFO(0x0bda, 0xc85d, 0xff, 0xff, 0xff), 46 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 47 + { USB_DEVICE_AND_INTERFACE_INFO(0x0db0, 0x991d, 0xff, 0xff, 0xff), 48 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 49 + { USB_DEVICE_AND_INTERFACE_INFO(0x35b2, 0x0502, 0xff, 0xff, 0xff), 50 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 51 + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0101, 0xff, 0xff, 0xff), 52 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 53 + { USB_DEVICE_AND_INTERFACE_INFO(0x35bc, 0x0102, 0xff, 0xff, 0xff), 54 + .driver_info = (kernel_ulong_t)&rtw89_8852cu_info }, 55 + {}, 56 + }; 57 + MODULE_DEVICE_TABLE(usb, rtw_8852cu_id_table); 58 + 59 + static struct usb_driver rtw_8852cu_driver = { 60 + .name = KBUILD_MODNAME, 61 + .id_table = rtw_8852cu_id_table, 62 + .probe = rtw89_usb_probe, 63 + .disconnect = rtw89_usb_disconnect, 64 + }; 65 + module_usb_driver(rtw_8852cu_driver); 66 + 67 + MODULE_AUTHOR("Bitterblue Smith <rtl8821cerfe2@gmail.com>"); 68 + MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852CU driver"); 69 + MODULE_LICENSE("Dual BSD/GPL");
+15 -2
drivers/net/wireless/realtek/rtw89/rtw8922a.c
··· 2347 2347 enum rtw89_band band = chan->band_type; 2348 2348 struct rtw89_hal *hal = &rtwdev->hal; 2349 2349 u8 ntx_path = RF_PATH_AB; 2350 + u8 nrx_path = RF_PATH_AB; 2350 2351 u32 tx_en0, tx_en1; 2352 + u8 rx_nss = 2; 2351 2353 2352 2354 if (hal->antenna_tx == RF_A) 2353 2355 ntx_path = RF_PATH_A; 2354 2356 else if (hal->antenna_tx == RF_B) 2355 2357 ntx_path = RF_PATH_B; 2356 2358 2359 + if (hal->antenna_rx == RF_A) 2360 + nrx_path = RF_PATH_A; 2361 + else if (hal->antenna_rx == RF_B) 2362 + nrx_path = RF_PATH_B; 2363 + 2364 + if (nrx_path != RF_PATH_AB) 2365 + rx_nss = 1; 2366 + 2357 2367 rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, true); 2358 2368 if (rtwdev->dbcc_en) 2359 2369 rtw8922a_hal_reset(rtwdev, RTW89_PHY_1, RTW89_MAC_1, band, 2360 2370 &tx_en1, true); 2361 2371 2362 - rtw8922a_ctrl_trx_path(rtwdev, ntx_path, 2, RF_PATH_AB, 2); 2372 + rtw8922a_ctrl_trx_path(rtwdev, ntx_path, 2, nrx_path, rx_nss); 2363 2373 2364 2374 rtw8922a_hal_reset(rtwdev, RTW89_PHY_0, RTW89_MAC_0, band, &tx_en0, false); 2365 2375 if (rtwdev->dbcc_en) ··· 2831 2821 .query_rxdesc = rtw89_core_query_rxdesc_v2, 2832 2822 .fill_txdesc = rtw89_core_fill_txdesc_v2, 2833 2823 .fill_txdesc_fwcmd = rtw89_core_fill_txdesc_fwcmd_v2, 2834 - .get_ch_dma = rtw89_core_get_ch_dma, 2824 + .get_ch_dma = {rtw89_core_get_ch_dma, 2825 + rtw89_core_get_ch_dma_v2, 2826 + NULL,}, 2835 2827 .cfg_ctrl_path = rtw89_mac_cfg_ctrl_path_v2, 2836 2828 .mac_cfg_gnt = rtw89_mac_cfg_gnt_v2, 2837 2829 .stop_sch_tx = rtw89_mac_stop_sch_tx_v2, ··· 2931 2919 .bacam_num = 24, 2932 2920 .bacam_dynamic_num = 8, 2933 2921 .bacam_ver = RTW89_BACAM_V1, 2922 + .addrcam_ver = 0, 2934 2923 .ppdu_max_usr = 16, 2935 2924 .sec_ctrl_efuse_size = 4, 2936 2925 .physical_efuse_size = 0x1300,
+6 -1
drivers/net/wireless/realtek/rtw89/txrx.h
··· 127 127 #define RTW89_TXWD_INFO0_MULTIPORT_ID GENMASK(6, 4) 128 128 129 129 /* TX WD INFO DWORD 1 */ 130 + #define RTW89_TXWD_INFO1_DATA_TXCNT_LMT_SEL BIT(31) 131 + #define RTW89_TXWD_INFO1_DATA_TXCNT_LMT GENMASK(30, 25) 130 132 #define RTW89_TXWD_INFO1_DATA_RTY_LOWEST_RATE GENMASK(24, 16) 131 133 #define RTW89_TXWD_INFO1_A_CTRL_BSR BIT(14) 132 134 #define RTW89_TXWD_INFO1_MAX_AGGNUM GENMASK(7, 0) ··· 141 139 #define RTW89_TXWD_INFO2_SEC_CAM_IDX GENMASK(7, 0) 142 140 143 141 /* TX WD INFO DWORD 3 */ 142 + #define RTW89_TXWD_INFO3_SPE_RPT BIT(10) 144 143 145 144 /* TX WD INFO DWORD 4 */ 146 - #define RTW89_TXWD_INFO4_RTS_EN BIT(27) 147 145 #define RTW89_TXWD_INFO4_HW_RTS_EN BIT(31) 146 + #define RTW89_TXWD_INFO4_RTS_EN BIT(27) 147 + #define RTW89_TXWD_INFO4_SW_DEFINE GENMASK(3, 0) 148 148 149 149 /* TX WD INFO DWORD 5 */ 150 150 ··· 421 417 #define RTW89_RXINFO_USER_MGMT BIT(3) 422 418 #define RTW89_RXINFO_USER_BCN BIT(4) 423 419 #define RTW89_RXINFO_USER_MACID GENMASK(15, 8) 420 + #define RTW89_RXINFO_USER_MACID_V1 GENMASK(31, 20) 424 421 425 422 struct rtw89_rxinfo { 426 423 __le32 w0;
+72 -43
drivers/net/wireless/realtek/rtw89/usb.c
··· 55 55 else if (ret < 0) 56 56 rtw89_warn(rtwdev, 57 57 "usb %s%u 0x%x fail ret=%d value=0x%x attempt=%d\n", 58 - reqtype == RTW89_USB_VENQT_READ ? "read" : "write", 58 + str_read_write(reqtype == RTW89_USB_VENQT_READ), 59 59 len * 8, addr, ret, 60 60 le32_to_cpup(rtwusb->vendor_req_buf), 61 61 attempt); ··· 167 167 return 42; /* TODO some kind of calculation? */ 168 168 } 169 169 170 - static u8 rtw89_usb_get_bulkout_id(u8 ch_dma) 171 - { 172 - switch (ch_dma) { 173 - case RTW89_DMA_ACH0: 174 - return 3; 175 - case RTW89_DMA_ACH1: 176 - return 4; 177 - case RTW89_DMA_ACH2: 178 - return 5; 179 - case RTW89_DMA_ACH3: 180 - return 6; 181 - default: 182 - case RTW89_DMA_B0MG: 183 - return 0; 184 - case RTW89_DMA_B0HI: 185 - return 1; 186 - case RTW89_DMA_H2C: 187 - return 2; 188 - } 189 - } 190 - 191 170 static void rtw89_usb_write_port_complete(struct urb *urb) 192 171 { 193 172 struct rtw89_usb_tx_ctrl_block *txcb = urb->context; ··· 193 214 txdesc_size += rtwdev->chip->txwd_info_size; 194 215 195 216 skb_pull(skb, txdesc_size); 217 + 218 + if (rtw89_is_tx_rpt_skb(rtwdev, skb)) { 219 + if (urb->status == 0) 220 + rtw89_tx_rpt_skb_add(rtwdev, skb); 221 + else 222 + rtw89_tx_rpt_tx_status(rtwdev, skb, 223 + RTW89_TX_MACID_DROP); 224 + continue; 225 + } 196 226 197 227 info = IEEE80211_SKB_CB(skb); 198 228 ieee80211_tx_info_clear_status(info); ··· 230 242 } 231 243 232 244 kfree(txcb); 233 - usb_free_urb(urb); 234 245 } 235 246 236 247 static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma, 237 248 void *data, int len, void *context) 238 249 { 239 250 struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); 251 + const struct rtw89_usb_info *info = rtwusb->info; 240 252 struct usb_device *usbd = rtwusb->udev; 241 253 struct urb *urb; 242 - u8 bulkout_id = rtw89_usb_get_bulkout_id(ch_dma); 254 + u8 bulkout_id = info->bulkout_id[ch_dma]; 243 255 unsigned int pipe; 244 256 int ret; 245 257 246 258 if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) 247 - return 0; 259 + return -ENODEV; 248 260 249 261 urb = usb_alloc_urb(0, GFP_ATOMIC); 250 262 if (!urb) ··· 255 267 usb_fill_bulk_urb(urb, usbd, pipe, data, len, 256 268 rtw89_usb_write_port_complete, context); 257 269 urb->transfer_flags |= URB_ZERO_PACKET; 258 - ret = usb_submit_urb(urb, GFP_ATOMIC); 270 + usb_anchor_urb(urb, &rtwusb->tx_submitted); 259 271 272 + ret = usb_submit_urb(urb, GFP_ATOMIC); 260 273 if (ret) 261 - usb_free_urb(urb); 274 + usb_unanchor_urb(urb); 275 + 276 + /* release our reference to this URB, USB core will eventually free it 277 + * on its own after the completion callback finishes (or URB is 278 + * immediately freed here if its submission has failed) 279 + */ 280 + usb_free_urb(urb); 262 281 263 282 if (ret == -ENODEV) 264 283 set_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags); 265 284 266 285 return ret; 286 + } 287 + 288 + static void rtw89_usb_tx_free_skb(struct rtw89_dev *rtwdev, u8 txch, 289 + struct sk_buff *skb) 290 + { 291 + if (txch == RTW89_TXCH_CH12) 292 + dev_kfree_skb_any(skb); 293 + else 294 + ieee80211_free_txskb(rtwdev->hw, skb); 267 295 } 268 296 269 297 static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) ··· 296 292 297 293 txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC); 298 294 if (!txcb) { 299 - dev_kfree_skb_any(skb); 295 + rtw89_usb_tx_free_skb(rtwdev, txch, skb); 300 296 continue; 301 297 } 302 298 ··· 309 305 ret = rtw89_usb_write_port(rtwdev, txch, skb->data, skb->len, 310 306 txcb); 311 307 if (ret) { 312 - rtw89_err(rtwdev, "write port txch %d failed: %d\n", 313 - txch, ret); 308 + if (ret != -ENODEV) 309 + rtw89_err(rtwdev, "write port txch %d failed: %d\n", 310 + txch, ret); 314 311 315 312 skb_dequeue(&txcb->tx_ack_queue); 316 313 kfree(txcb); 317 - dev_kfree_skb_any(skb); 314 + rtw89_usb_tx_free_skb(rtwdev, txch, skb); 318 315 } 319 316 } 320 317 } ··· 367 362 { 368 363 struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; 369 364 struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); 365 + struct rtw89_tx_skb_data *skb_data; 370 366 struct sk_buff *skb = tx_req->skb; 371 367 struct rtw89_txwd_body *txdesc; 372 368 u32 txdesc_size; ··· 394 388 395 389 le32p_replace_bits(&txdesc->dword0, 1, RTW89_TXWD_BODY0_STF_MODE); 396 390 391 + skb_data = RTW89_TX_SKB_CB(skb); 392 + if (tx_req->desc_info.sn) 393 + skb_data->tx_rpt_sn = tx_req->desc_info.sn; 394 + if (tx_req->desc_info.tx_cnt_lmt) 395 + skb_data->tx_pkt_cnt_lmt = tx_req->desc_info.tx_cnt_lmt; 396 + 397 397 skb_queue_tail(&rtwusb->tx_queue[desc_info->ch_dma], skb); 398 398 399 399 return 0; ··· 422 410 423 411 if (skb_queue_len(&rtwusb->rx_queue) >= RTW89_USB_MAX_RXQ_LEN) { 424 412 rtw89_warn(rtwdev, "rx_queue overflow\n"); 425 - dev_kfree_skb_any(rx_skb); 426 - continue; 413 + goto free_or_reuse; 427 414 } 428 415 429 416 memset(&desc_info, 0, sizeof(desc_info)); ··· 433 422 rtw89_debug(rtwdev, RTW89_DBG_HCI, 434 423 "failed to allocate RX skb of size %u\n", 435 424 desc_info.pkt_size); 436 - continue; 425 + goto free_or_reuse; 437 426 } 438 427 439 428 pkt_offset = desc_info.offset + desc_info.rxd_len; ··· 443 432 444 433 rtw89_core_rx(rtwdev, &desc_info, skb); 445 434 435 + free_or_reuse: 446 436 if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW89_USB_RX_SKB_NUM) 447 437 dev_kfree_skb_any(rx_skb); 448 438 else ··· 579 567 } 580 568 } 581 569 570 + static void rtw89_usb_cancel_tx_bufs(struct rtw89_usb *rtwusb) 571 + { 572 + usb_kill_anchored_urbs(&rtwusb->tx_submitted); 573 + } 574 + 582 575 static void rtw89_usb_free_rx_bufs(struct rtw89_usb *rtwusb) 583 576 { 584 577 struct rtw89_usb_rx_ctrl_block *rxcb; ··· 685 668 686 669 static void rtw89_usb_ops_reset(struct rtw89_dev *rtwdev) 687 670 { 688 - /* TODO: anything to do here? */ 671 + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); 672 + 673 + rtw89_usb_cancel_tx_bufs(rtwusb); 674 + rtw89_tx_rpt_skbs_purge(rtwdev); 689 675 } 690 676 691 677 static int rtw89_usb_ops_start(struct rtw89_dev *rtwdev) ··· 718 698 719 699 static int rtw89_usb_ops_mac_pre_init(struct rtw89_dev *rtwdev) 720 700 { 701 + struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); 702 + const struct rtw89_usb_info *info = rtwusb->info; 721 703 u32 val32; 722 704 723 - rtw89_write32_set(rtwdev, R_AX_USB_HOST_REQUEST_2, B_AX_R_USBIO_MODE); 705 + rtw89_write32_set(rtwdev, info->usb_host_request_2, 706 + B_AX_R_USBIO_MODE); 724 707 725 708 /* fix USB IO hang suggest by chihhanli@realtek.com */ 726 - rtw89_write32_clr(rtwdev, R_AX_USB_WLAN0_1, 709 + rtw89_write32_clr(rtwdev, info->usb_wlan0_1, 727 710 B_AX_USBRX_RST | B_AX_USBTX_RST); 728 711 729 - val32 = rtw89_read32(rtwdev, R_AX_HCI_FUNC_EN); 712 + val32 = rtw89_read32(rtwdev, info->hci_func_en); 730 713 val32 &= ~(B_AX_HCI_RXDMA_EN | B_AX_HCI_TXDMA_EN); 731 - rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val32); 714 + rtw89_write32(rtwdev, info->hci_func_en, val32); 732 715 733 716 val32 |= B_AX_HCI_RXDMA_EN | B_AX_HCI_TXDMA_EN; 734 - rtw89_write32(rtwdev, R_AX_HCI_FUNC_EN, val32); 717 + rtw89_write32(rtwdev, info->hci_func_en, val32); 735 718 /* fix USB TRX hang suggest by chihhanli@realtek.com */ 736 719 737 720 return 0; ··· 748 725 static int rtw89_usb_ops_mac_post_init(struct rtw89_dev *rtwdev) 749 726 { 750 727 struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); 728 + const struct rtw89_usb_info *info = rtwusb->info; 751 729 enum usb_device_speed speed; 752 730 u32 ep; 753 731 754 - rtw89_write32_clr(rtwdev, R_AX_USB3_MAC_NPI_CONFIG_INTF_0, 732 + rtw89_write32_clr(rtwdev, info->usb3_mac_npi_config_intf_0, 755 733 B_AX_SSPHY_LFPS_FILTER); 756 734 757 735 speed = rtwusb->udev->speed; ··· 768 744 if (ep == 8) 769 745 continue; 770 746 771 - rtw89_write8_mask(rtwdev, R_AX_USB_ENDPOINT_0, 747 + rtw89_write8_mask(rtwdev, info->usb_endpoint_0, 772 748 B_AX_EP_IDX, ep); 773 - rtw89_write8(rtwdev, R_AX_USB_ENDPOINT_2 + 1, NUMP); 749 + rtw89_write8(rtwdev, info->usb_endpoint_2 + 1, NUMP); 774 750 } 775 751 776 752 return 0; ··· 925 901 struct rtw89_usb *rtwusb = rtw89_usb_priv(rtwdev); 926 902 int ret; 927 903 904 + init_usb_anchor(&rtwusb->tx_submitted); 905 + 928 906 ret = rtw89_usb_parse(rtwdev, intf); 929 907 if (ret) 930 908 return ret; ··· 975 949 976 950 rtwusb = rtw89_usb_priv(rtwdev); 977 951 rtwusb->rtwdev = rtwdev; 952 + rtwusb->info = info->bus.usb; 978 953 979 954 rtwdev->hci.ops = &rtw89_usb_ops; 980 955 rtwdev->hci.type = RTW89_HCI_TYPE_USB; 956 + rtwdev->hci.tx_rpt_enabled = true; 981 957 982 958 ret = rtw89_usb_intf_init(rtwdev, intf); 983 959 if (ret) { ··· 1054 1026 rtwusb = rtw89_usb_priv(rtwdev); 1055 1027 1056 1028 rtw89_usb_cancel_rx_bufs(rtwusb); 1029 + rtw89_usb_cancel_tx_bufs(rtwusb); 1057 1030 1058 1031 rtw89_core_unregister(rtwdev); 1059 1032 rtw89_core_deinit(rtwdev);
+12
drivers/net/wireless/realtek/rtw89/usb.h
··· 20 20 #define RTW89_MAX_ENDPOINT_NUM 9 21 21 #define RTW89_MAX_BULKOUT_NUM 7 22 22 23 + struct rtw89_usb_info { 24 + u32 usb_host_request_2; 25 + u32 usb_wlan0_1; 26 + u32 hci_func_en; 27 + u32 usb3_mac_npi_config_intf_0; 28 + u32 usb_endpoint_0; 29 + u32 usb_endpoint_2; 30 + u8 bulkout_id[RTW89_DMA_CH_NUM]; 31 + }; 32 + 23 33 struct rtw89_usb_rx_ctrl_block { 24 34 struct rtw89_dev *rtwdev; 25 35 struct urb *rx_urb; ··· 45 35 struct rtw89_usb { 46 36 struct rtw89_dev *rtwdev; 47 37 struct usb_device *udev; 38 + const struct rtw89_usb_info *info; 48 39 49 40 __le32 *vendor_req_buf; 50 41 ··· 60 49 struct sk_buff_head rx_free_queue; 61 50 struct work_struct rx_work; 62 51 struct work_struct rx_urb_work; 52 + struct usb_anchor tx_submitted; 63 53 64 54 struct sk_buff_head tx_queue[RTW89_TXCH_NUM]; 65 55 };
+5 -3
drivers/net/wireless/realtek/rtw89/wow.c
··· 1221 1221 } 1222 1222 } 1223 1223 1224 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); 1224 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 1225 + RTW89_ROLE_INFO_CHANGE); 1225 1226 if (ret) { 1226 1227 rtw89_warn(rtwdev, "failed to send h2c cam\n"); 1227 1228 return ret; ··· 1249 1248 mac->wow_ctrl.addr, mac->wow_ctrl.mask); 1250 1249 if (ret) 1251 1250 rtw89_err(rtwdev, "failed to check wow status %s\n", 1252 - wow_enable ? "enabled" : "disabled"); 1251 + str_enabled_disabled(wow_enable)); 1253 1252 return ret; 1254 1253 } 1255 1254 ··· 1319 1318 return ret; 1320 1319 } 1321 1320 1322 - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL); 1321 + ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL, 1322 + RTW89_ROLE_FW_RESTORE); 1323 1323 if (ret) { 1324 1324 rtw89_warn(rtwdev, "failed to send h2c cam\n"); 1325 1325 return ret;
+1 -1
drivers/net/wireless/silabs/wfx/main.c
··· 364 364 wdev->pdata.gpio_wakeup = NULL; 365 365 wdev->poll_irq = true; 366 366 367 - wdev->bh_wq = alloc_workqueue("wfx_bh_wq", WQ_HIGHPRI, 0); 367 + wdev->bh_wq = alloc_workqueue("wfx_bh_wq", WQ_HIGHPRI | WQ_PERCPU, 0); 368 368 if (!wdev->bh_wq) 369 369 return -ENOMEM; 370 370
+3 -2
drivers/net/wireless/st/cw1200/bh.c
··· 54 54 int err = 0; 55 55 /* Realtime workqueue */ 56 56 priv->bh_workqueue = alloc_workqueue("cw1200_bh", 57 - WQ_MEM_RECLAIM | WQ_HIGHPRI 58 - | WQ_CPU_INTENSIVE, 1); 57 + WQ_MEM_RECLAIM | WQ_HIGHPRI | 58 + WQ_CPU_INTENSIVE | WQ_PERCPU, 59 + 1); 59 60 60 61 if (!priv->bh_workqueue) 61 62 return -ENOMEM;
+1
include/linux/ieee80211-he.h
··· 548 548 #define IEEE80211_6GHZ_CTRL_REG_VLP_AP 2 549 549 #define IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP 3 550 550 #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP_OLD 4 551 + #define IEEE80211_6GHZ_CTRL_REG_AP_ROLE_NOT_RELEVANT 7 551 552 #define IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP 8 552 553 553 554 /**
+15 -3
include/linux/ieee80211.h
··· 1207 1207 #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) 1208 1208 1209 1209 1210 - /* Management MIC information element (IEEE 802.11w) */ 1210 + /* Management MIC information element (IEEE 802.11w) for CMAC */ 1211 1211 struct ieee80211_mmie { 1212 1212 u8 element_id; 1213 1213 u8 length; ··· 1223 1223 __le16 key_id; 1224 1224 u8 sequence_number[6]; 1225 1225 u8 mic[16]; 1226 + } __packed; 1227 + 1228 + /* Management MIC information element (IEEE 802.11w) for all variants */ 1229 + struct ieee80211_mmie_var { 1230 + u8 element_id; 1231 + u8 length; 1232 + __le16 key_id; 1233 + u8 sequence_number[6]; 1234 + u8 mic[]; /* 8 or 16 bytes */ 1226 1235 } __packed; 1227 1236 1228 1237 struct ieee80211_vendor_ie { ··· 1493 1484 WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, 1494 1485 WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, 1495 1486 /* 802.11ai */ 1496 - WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, 1497 - WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, 1487 + WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, 1488 + WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, 1498 1489 WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, 1499 1490 WLAN_STATUS_SAE_PK = 127, 1500 1491 WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING = 133, ··· 1898 1889 #define IEEE80211_GCMP_HDR_LEN 8 1899 1890 #define IEEE80211_GCMP_MIC_LEN 16 1900 1891 #define IEEE80211_GCMP_PN_LEN 6 1892 + #define IEEE80211_CMAC_128_MIC_LEN 8 1893 + #define IEEE80211_CMAC_256_MIC_LEN 16 1894 + #define IEEE80211_GMAC_MIC_LEN 16 1901 1895 1902 1896 #define FILS_NONCE_LEN 16 1903 1897 #define FILS_MAX_KEK_LEN 64
+1
include/linux/soc/airoha/airoha_offload.h
··· 6 6 #ifndef AIROHA_OFFLOAD_H 7 7 #define AIROHA_OFFLOAD_H 8 8 9 + #include <linux/skbuff.h> 9 10 #include <linux/spinlock.h> 10 11 #include <linux/workqueue.h> 11 12
+1
include/linux/soc/mediatek/mtk_wed.h
··· 154 154 bool wcid_512; 155 155 bool hw_rro; 156 156 bool msi; 157 + bool hif2; 157 158 158 159 u16 token_start; 159 160 unsigned int nbuf;
+3 -1
include/net/cfg80211.h
··· 974 974 chandef1->center_freq1 == chandef2->center_freq1 && 975 975 chandef1->freq1_offset == chandef2->freq1_offset && 976 976 chandef1->center_freq2 == chandef2->center_freq2 && 977 - chandef1->punctured == chandef2->punctured); 977 + chandef1->punctured == chandef2->punctured && 978 + chandef1->s1g_primary_2mhz == chandef2->s1g_primary_2mhz); 978 979 } 979 980 980 981 /** ··· 10149 10148 switch (u8_get_bits(control, IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) { 10150 10149 case IEEE80211_6GHZ_CTRL_REG_LPI_AP: 10151 10150 case IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP: 10151 + case IEEE80211_6GHZ_CTRL_REG_AP_ROLE_NOT_RELEVANT: 10152 10152 return IEEE80211_REG_LPI_AP; 10153 10153 case IEEE80211_6GHZ_CTRL_REG_SP_AP: 10154 10154 case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP_OLD:
-1
include/uapi/linux/nl80211-vnd-intel.h
··· 84 84 * 85 85 * @NUM_IWL_MVM_VENDOR_ATTR: number of vendor attributes 86 86 * @MAX_IWL_MVM_VENDOR_ATTR: highest vendor attribute number 87 - 88 87 */ 89 88 enum iwl_mvm_vendor_attr { 90 89 __IWL_MVM_VENDOR_ATTR_INVALID = 0x00,
+26 -34
net/mac80211/aes_cmac.c
··· 16 16 #include "key.h" 17 17 #include "aes_cmac.h" 18 18 19 - #define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */ 20 - #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ 21 19 #define AAD_LEN 20 22 20 23 - static const u8 zero[CMAC_TLEN_256]; 21 + static const u8 zero[IEEE80211_CMAC_256_MIC_LEN]; 24 22 25 - void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 26 - const u8 *data, size_t data_len, u8 *mic) 23 + int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 24 + const u8 *data, size_t data_len, u8 *mic, 25 + unsigned int mic_len) 27 26 { 27 + int err; 28 28 SHASH_DESC_ON_STACK(desc, tfm); 29 29 u8 out[AES_BLOCK_SIZE]; 30 30 const __le16 *fc; 31 31 32 32 desc->tfm = tfm; 33 33 34 - crypto_shash_init(desc); 35 - crypto_shash_update(desc, aad, AAD_LEN); 34 + err = crypto_shash_init(desc); 35 + if (err) 36 + return err; 37 + err = crypto_shash_update(desc, aad, AAD_LEN); 38 + if (err) 39 + return err; 36 40 fc = (const __le16 *)aad; 37 41 if (ieee80211_is_beacon(*fc)) { 38 42 /* mask Timestamp field to zero */ 39 - crypto_shash_update(desc, zero, 8); 40 - crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); 43 + err = crypto_shash_update(desc, zero, 8); 44 + if (err) 45 + return err; 46 + err = crypto_shash_update(desc, data + 8, 47 + data_len - 8 - mic_len); 48 + if (err) 49 + return err; 41 50 } else { 42 - crypto_shash_update(desc, data, data_len - CMAC_TLEN); 51 + err = crypto_shash_update(desc, data, data_len - mic_len); 52 + if (err) 53 + return err; 43 54 } 44 - crypto_shash_finup(desc, zero, CMAC_TLEN, out); 55 + err = crypto_shash_finup(desc, zero, mic_len, out); 56 + if (err) 57 + return err; 58 + memcpy(mic, out, mic_len); 45 59 46 - memcpy(mic, out, CMAC_TLEN); 47 - } 48 - 49 - void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, 50 - const u8 *data, size_t data_len, u8 *mic) 51 - { 52 - SHASH_DESC_ON_STACK(desc, tfm); 53 - const __le16 *fc; 54 - 55 - desc->tfm = tfm; 56 - 57 - crypto_shash_init(desc); 58 - crypto_shash_update(desc, aad, AAD_LEN); 59 - fc = (const __le16 *)aad; 60 - if (ieee80211_is_beacon(*fc)) { 61 - /* mask Timestamp field to zero */ 62 - crypto_shash_update(desc, zero, 8); 63 - crypto_shash_update(desc, data + 8, 64 - data_len - 8 - CMAC_TLEN_256); 65 - } else { 66 - crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); 67 - } 68 - crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); 60 + return 0; 69 61 } 70 62 71 63 struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
+3 -4
net/mac80211/aes_cmac.h
··· 11 11 12 12 struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], 13 13 size_t key_len); 14 - void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 15 - const u8 *data, size_t data_len, u8 *mic); 16 - void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, 17 - const u8 *data, size_t data_len, u8 *mic); 14 + int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, 15 + const u8 *data, size_t data_len, u8 *mic, 16 + unsigned int mic_len); 18 17 void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); 19 18 20 19 #endif /* AES_CMAC_H */
+12 -10
net/mac80211/aes_gmac.c
··· 24 24 const __le16 *fc; 25 25 int ret; 26 26 27 - if (data_len < GMAC_MIC_LEN) 27 + if (data_len < IEEE80211_GMAC_MIC_LEN) 28 28 return -EINVAL; 29 29 30 - aead_req = kzalloc(reqsize + GMAC_MIC_LEN + GMAC_AAD_LEN, GFP_ATOMIC); 30 + aead_req = kzalloc(reqsize + IEEE80211_GMAC_MIC_LEN + GMAC_AAD_LEN, 31 + GFP_ATOMIC); 31 32 if (!aead_req) 32 33 return -ENOMEM; 33 34 34 35 zero = (u8 *)aead_req + reqsize; 35 - __aad = zero + GMAC_MIC_LEN; 36 + __aad = zero + IEEE80211_GMAC_MIC_LEN; 36 37 memcpy(__aad, aad, GMAC_AAD_LEN); 37 38 38 39 fc = (const __le16 *)aad; ··· 42 41 sg_init_table(sg, 5); 43 42 sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN); 44 43 sg_set_buf(&sg[1], zero, 8); 45 - sg_set_buf(&sg[2], data + 8, data_len - 8 - GMAC_MIC_LEN); 46 - sg_set_buf(&sg[3], zero, GMAC_MIC_LEN); 47 - sg_set_buf(&sg[4], mic, GMAC_MIC_LEN); 44 + sg_set_buf(&sg[2], data + 8, 45 + data_len - 8 - IEEE80211_GMAC_MIC_LEN); 46 + sg_set_buf(&sg[3], zero, IEEE80211_GMAC_MIC_LEN); 47 + sg_set_buf(&sg[4], mic, IEEE80211_GMAC_MIC_LEN); 48 48 } else { 49 49 sg_init_table(sg, 4); 50 50 sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN); 51 - sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN); 52 - sg_set_buf(&sg[2], zero, GMAC_MIC_LEN); 53 - sg_set_buf(&sg[3], mic, GMAC_MIC_LEN); 51 + sg_set_buf(&sg[1], data, data_len - IEEE80211_GMAC_MIC_LEN); 52 + sg_set_buf(&sg[2], zero, IEEE80211_GMAC_MIC_LEN); 53 + sg_set_buf(&sg[3], mic, IEEE80211_GMAC_MIC_LEN); 54 54 } 55 55 56 56 memcpy(iv, nonce, GMAC_NONCE_LEN); ··· 80 78 81 79 err = crypto_aead_setkey(tfm, key, key_len); 82 80 if (!err) 83 - err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN); 81 + err = crypto_aead_setauthsize(tfm, IEEE80211_GMAC_MIC_LEN); 84 82 if (!err) 85 83 return tfm; 86 84
-1
net/mac80211/aes_gmac.h
··· 9 9 #include <linux/crypto.h> 10 10 11 11 #define GMAC_AAD_LEN 20 12 - #define GMAC_MIC_LEN 16 13 12 #define GMAC_NONCE_LEN 12 14 13 15 14 struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
+13 -2
net/mac80211/chan.c
··· 654 654 }; 655 655 u32 changed = 0; 656 656 657 - /* expected to handle only 20/40/80/160/320 channel widths */ 657 + /* 5/10 MHz not handled here */ 658 658 switch (chandef->width) { 659 + case NL80211_CHAN_WIDTH_1: 660 + case NL80211_CHAN_WIDTH_2: 661 + case NL80211_CHAN_WIDTH_4: 662 + case NL80211_CHAN_WIDTH_8: 663 + case NL80211_CHAN_WIDTH_16: 664 + /* 665 + * mac80211 currently only supports sharing identical 666 + * chanctx's for S1G interfaces. 667 + */ 668 + WARN_ON(!ieee80211_chanreq_identical(&ctx_req, chanreq)); 669 + return; 659 670 case NL80211_CHAN_WIDTH_20_NOHT: 660 671 case NL80211_CHAN_WIDTH_20: 661 672 case NL80211_CHAN_WIDTH_40: ··· 1726 1715 n_reserved = 0; 1727 1716 n_ready = 0; 1728 1717 1729 - for_each_chanctx_user_assigned(local, ctx, &iter) { 1718 + for_each_chanctx_user_assigned(local, ctx->replace_ctx, &iter) { 1730 1719 n_assigned++; 1731 1720 if (iter.link->reserved_chanctx) { 1732 1721 n_reserved++;
+3 -2
net/mac80211/mlme.c
··· 6108 6108 ret = ieee80211_link_use_channel(link, &chanreq, 6109 6109 IEEE80211_CHANCTX_SHARED); 6110 6110 6111 - /* don't downgrade for 5 and 10 MHz channels, though. */ 6111 + /* don't downgrade for 5/10/S1G MHz channels, though. */ 6112 6112 if (chanreq.oper.width == NL80211_CHAN_WIDTH_5 || 6113 - chanreq.oper.width == NL80211_CHAN_WIDTH_10) 6113 + chanreq.oper.width == NL80211_CHAN_WIDTH_10 || 6114 + cfg80211_chandef_is_s1g(&chanreq.oper)) 6114 6115 return ret; 6115 6116 6116 6117 while (ret && chanreq.oper.width != NL80211_CHAN_WIDTH_20_NOHT) {
+4 -2
net/mac80211/rx.c
··· 2215 2215 rx, IEEE80211_CCMP_256_MIC_LEN); 2216 2216 break; 2217 2217 case WLAN_CIPHER_SUITE_AES_CMAC: 2218 - result = ieee80211_crypto_aes_cmac_decrypt(rx); 2218 + result = ieee80211_crypto_aes_cmac_decrypt( 2219 + rx, IEEE80211_CMAC_128_MIC_LEN); 2219 2220 break; 2220 2221 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 2221 - result = ieee80211_crypto_aes_cmac_256_decrypt(rx); 2222 + result = ieee80211_crypto_aes_cmac_decrypt( 2223 + rx, IEEE80211_CMAC_256_MIC_LEN); 2222 2224 break; 2223 2225 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 2224 2226 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+4 -2
net/mac80211/tx.c
··· 1062 1062 return ieee80211_crypto_ccmp_encrypt( 1063 1063 tx, IEEE80211_CCMP_256_MIC_LEN); 1064 1064 case WLAN_CIPHER_SUITE_AES_CMAC: 1065 - return ieee80211_crypto_aes_cmac_encrypt(tx); 1065 + return ieee80211_crypto_aes_cmac_encrypt( 1066 + tx, IEEE80211_CMAC_128_MIC_LEN); 1066 1067 case WLAN_CIPHER_SUITE_BIP_CMAC_256: 1067 - return ieee80211_crypto_aes_cmac_256_encrypt(tx); 1068 + return ieee80211_crypto_aes_cmac_encrypt( 1069 + tx, IEEE80211_CMAC_256_MIC_LEN); 1068 1070 case WLAN_CIPHER_SUITE_BIP_GMAC_128: 1069 1071 case WLAN_CIPHER_SUITE_BIP_GMAC_256: 1070 1072 return ieee80211_crypto_aes_gmac_encrypt(tx);
+31 -119
net/mac80211/wpa.c
··· 828 828 829 829 830 830 ieee80211_tx_result 831 - ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) 831 + ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx, 832 + unsigned int mic_len) 832 833 { 833 834 struct sk_buff *skb; 834 835 struct ieee80211_tx_info *info; 835 836 struct ieee80211_key *key = tx->key; 836 - struct ieee80211_mmie *mmie; 837 + struct ieee80211_mmie_var *mmie; 838 + size_t mmie_len; 837 839 u8 aad[20]; 838 840 u64 pn64; 839 841 ··· 850 848 !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE)) 851 849 return TX_CONTINUE; 852 850 853 - if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) 851 + mmie_len = sizeof(*mmie) + mic_len; 852 + 853 + if (WARN_ON(skb_tailroom(skb) < mmie_len)) 854 854 return TX_DROP; 855 855 856 - mmie = skb_put(skb, sizeof(*mmie)); 856 + mmie = skb_put(skb, mmie_len); 857 857 mmie->element_id = WLAN_EID_MMIE; 858 - mmie->length = sizeof(*mmie) - 2; 858 + mmie->length = mmie_len - 2; 859 859 mmie->key_id = cpu_to_le16(key->conf.keyidx); 860 860 861 861 /* PN = PN + 1 */ ··· 870 866 871 867 bip_aad(skb, aad); 872 868 873 - /* 874 - * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) 875 - */ 876 - ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 877 - skb->data + 24, skb->len - 24, mmie->mic); 878 - 879 - return TX_CONTINUE; 880 - } 881 - 882 - ieee80211_tx_result 883 - ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) 884 - { 885 - struct sk_buff *skb; 886 - struct ieee80211_tx_info *info; 887 - struct ieee80211_key *key = tx->key; 888 - struct ieee80211_mmie_16 *mmie; 889 - u8 aad[20]; 890 - u64 pn64; 891 - 892 - if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) 869 + if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 870 + skb->data + 24, skb->len - 24, 871 + mmie->mic, mic_len)) 893 872 return TX_DROP; 894 - 895 - skb = skb_peek(&tx->skbs); 896 - 897 - info = IEEE80211_SKB_CB(skb); 898 - 899 - if (info->control.hw_key && 900 - !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE)) 901 - return TX_CONTINUE; 902 - 903 - if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) 904 - return TX_DROP; 905 - 906 - mmie = skb_put(skb, sizeof(*mmie)); 907 - mmie->element_id = WLAN_EID_MMIE; 908 - mmie->length = sizeof(*mmie) - 2; 909 - mmie->key_id = cpu_to_le16(key->conf.keyidx); 910 - 911 - /* PN = PN + 1 */ 912 - pn64 = atomic64_inc_return(&key->conf.tx_pn); 913 - 914 - bip_ipn_set64(mmie->sequence_number, pn64); 915 - 916 - if (info->control.hw_key) 917 - return TX_CONTINUE; 918 - 919 - bip_aad(skb, aad); 920 - 921 - /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) 922 - */ 923 - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, 924 - skb->data + 24, skb->len - 24, mmie->mic); 925 873 926 874 return TX_CONTINUE; 927 875 } 928 876 929 877 ieee80211_rx_result 930 - ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) 878 + ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx, 879 + unsigned int mic_len) 931 880 { 932 881 struct sk_buff *skb = rx->skb; 933 882 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 934 883 struct ieee80211_key *key = rx->key; 935 - struct ieee80211_mmie *mmie; 936 - u8 aad[20], mic[8], ipn[6]; 884 + struct ieee80211_mmie_var *mmie; 885 + size_t mmie_len; 886 + u8 aad[20], mic[IEEE80211_CMAC_256_MIC_LEN], ipn[6]; 937 887 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 938 888 939 889 if (!ieee80211_is_mgmt(hdr->frame_control)) 940 890 return RX_CONTINUE; 941 891 892 + mmie_len = sizeof(*mmie) + mic_len; 893 + 942 894 /* management frames are already linear */ 943 895 944 - if (skb->len < 24 + sizeof(*mmie)) 945 - return RX_DROP_U_SHORT_CMAC; 896 + if (skb->len < 24 + mmie_len) 897 + return mic_len == IEEE80211_CMAC_128_MIC_LEN ? 898 + RX_DROP_U_SHORT_CMAC : RX_DROP_U_SHORT_CMAC256; 946 899 947 - mmie = (struct ieee80211_mmie *) 948 - (skb->data + skb->len - sizeof(*mmie)); 900 + mmie = (struct ieee80211_mmie_var *)(skb->data + skb->len - mmie_len); 949 901 if (mmie->element_id != WLAN_EID_MMIE || 950 - mmie->length != sizeof(*mmie) - 2) 902 + mmie->length != mmie_len - 2) 951 903 return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */ 952 904 953 905 bip_ipn_swap(ipn, mmie->sequence_number); ··· 916 956 if (!(status->flag & RX_FLAG_DECRYPTED)) { 917 957 /* hardware didn't decrypt/verify MIC */ 918 958 bip_aad(skb, aad); 919 - ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 920 - skb->data + 24, skb->len - 24, mic); 921 - if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { 959 + if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, 960 + skb->data + 24, skb->len - 24, 961 + mic, mic_len)) 962 + return RX_DROP_U_DECRYPT_FAIL; 963 + if (crypto_memneq(mic, mmie->mic, mic_len)) { 922 964 key->u.aes_cmac.icverrors++; 923 965 return RX_DROP_U_MIC_FAIL; 924 966 } ··· 929 967 memcpy(key->u.aes_cmac.rx_pn, ipn, 6); 930 968 931 969 /* Remove MMIE */ 932 - skb_trim(skb, skb->len - sizeof(*mmie)); 933 - 934 - return RX_CONTINUE; 935 - } 936 - 937 - ieee80211_rx_result 938 - ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) 939 - { 940 - struct sk_buff *skb = rx->skb; 941 - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 942 - struct ieee80211_key *key = rx->key; 943 - struct ieee80211_mmie_16 *mmie; 944 - u8 aad[20], mic[16], ipn[6]; 945 - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 946 - 947 - if (!ieee80211_is_mgmt(hdr->frame_control)) 948 - return RX_CONTINUE; 949 - 950 - /* management frames are already linear */ 951 - 952 - if (skb->len < 24 + sizeof(*mmie)) 953 - return RX_DROP_U_SHORT_CMAC256; 954 - 955 - mmie = (struct ieee80211_mmie_16 *) 956 - (skb->data + skb->len - sizeof(*mmie)); 957 - if (mmie->element_id != WLAN_EID_MMIE || 958 - mmie->length != sizeof(*mmie) - 2) 959 - return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */ 960 - 961 - bip_ipn_swap(ipn, mmie->sequence_number); 962 - 963 - if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) { 964 - key->u.aes_cmac.replays++; 965 - return RX_DROP_U_REPLAY; 966 - } 967 - 968 - if (!(status->flag & RX_FLAG_DECRYPTED)) { 969 - /* hardware didn't decrypt/verify MIC */ 970 - bip_aad(skb, aad); 971 - ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, 972 - skb->data + 24, skb->len - 24, mic); 973 - if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { 974 - key->u.aes_cmac.icverrors++; 975 - return RX_DROP_U_MIC_FAIL; 976 - } 977 - } 978 - 979 - memcpy(key->u.aes_cmac.rx_pn, ipn, 6); 980 - 981 - /* Remove MMIE */ 982 - skb_trim(skb, skb->len - sizeof(*mmie)); 970 + skb_trim(skb, skb->len - mmie_len); 983 971 984 972 return RX_CONTINUE; 985 973 } ··· 1025 1113 memcpy(nonce, hdr->addr2, ETH_ALEN); 1026 1114 memcpy(nonce + ETH_ALEN, ipn, 6); 1027 1115 1028 - mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC); 1116 + mic = kmalloc(IEEE80211_GMAC_MIC_LEN, GFP_ATOMIC); 1029 1117 if (!mic) 1030 1118 return RX_DROP_U_OOM; 1031 1119 if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
+4 -6
net/mac80211/wpa.h
··· 29 29 unsigned int mic_len); 30 30 31 31 ieee80211_tx_result 32 - ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx); 33 - ieee80211_tx_result 34 - ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx); 32 + ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx, 33 + unsigned int mic_len); 35 34 ieee80211_rx_result 36 - ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx); 37 - ieee80211_rx_result 38 - ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx); 35 + ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx, 36 + unsigned int mic_len); 39 37 ieee80211_tx_result 40 38 ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx); 41 39 ieee80211_rx_result
+3 -2
net/wireless/core.c
··· 431 431 if (wk) { 432 432 list_del_init(&wk->entry); 433 433 if (!list_empty(&rdev->wiphy_work_list)) 434 - queue_work(system_unbound_wq, work); 434 + queue_work(system_dfl_wq, work); 435 435 spin_unlock_irq(&rdev->wiphy_work_lock); 436 436 437 437 trace_wiphy_work_run(&rdev->wiphy, wk); ··· 1380 1380 1381 1381 cfg80211_pmsr_wdev_down(wdev); 1382 1382 1383 + cfg80211_stop_radar_detection(wdev); 1383 1384 cfg80211_stop_background_radar_detection(wdev); 1384 1385 1385 1386 switch (wdev->iftype) { ··· 1714 1713 list_add_tail(&work->entry, &rdev->wiphy_work_list); 1715 1714 spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); 1716 1715 1717 - queue_work(system_unbound_wq, &rdev->wiphy_work); 1716 + queue_work(system_dfl_wq, &rdev->wiphy_work); 1718 1717 } 1719 1718 EXPORT_SYMBOL_GPL(wiphy_work_queue); 1720 1719
+1
net/wireless/core.h
··· 489 489 struct wireless_dev *wdev, 490 490 struct cfg80211_chan_def *chandef); 491 491 492 + void cfg80211_stop_radar_detection(struct wireless_dev *wdev); 492 493 void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); 493 494 494 495 void cfg80211_background_cac_done_wk(struct work_struct *work);
+19
net/wireless/mlme.c
··· 1295 1295 return 0; 1296 1296 } 1297 1297 1298 + void cfg80211_stop_radar_detection(struct wireless_dev *wdev) 1299 + { 1300 + struct wiphy *wiphy = wdev->wiphy; 1301 + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 1302 + int link_id; 1303 + 1304 + for_each_valid_link(wdev, link_id) { 1305 + struct cfg80211_chan_def chandef; 1306 + 1307 + if (!wdev->links[link_id].cac_started) 1308 + continue; 1309 + 1310 + chandef = *wdev_chandef(wdev, link_id); 1311 + rdev_end_cac(rdev, wdev->netdev, link_id); 1312 + nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED, 1313 + wdev->netdev, GFP_KERNEL); 1314 + } 1315 + } 1316 + 1298 1317 void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) 1299 1318 { 1300 1319 struct wiphy *wiphy = wdev->wiphy;
+3
net/wireless/nl80211.c
··· 4178 4178 if (chandef->punctured && 4179 4179 nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP, chandef->punctured)) 4180 4180 return -ENOBUFS; 4181 + if (chandef->s1g_primary_2mhz && 4182 + nla_put_flag(msg, NL80211_ATTR_S1G_PRIMARY_2MHZ)) 4183 + return -ENOBUFS; 4181 4184 4182 4185 return 0; 4183 4186 }
+1 -1
net/wireless/sysfs.c
··· 137 137 if (rdev->wiphy.registered && rdev->ops->resume) 138 138 ret = rdev_resume(rdev); 139 139 rdev->suspended = false; 140 - queue_work(system_unbound_wq, &rdev->wiphy_work); 140 + queue_work(system_dfl_wq, &rdev->wiphy_work); 141 141 wiphy_unlock(&rdev->wiphy); 142 142 143 143 if (ret)
+1 -22
net/wireless/util.c
··· 1203 1203 dev->ieee80211_ptr->use_4addr = false; 1204 1204 rdev_set_qos_map(rdev, dev, NULL); 1205 1205 1206 - switch (otype) { 1207 - case NL80211_IFTYPE_AP: 1208 - case NL80211_IFTYPE_P2P_GO: 1209 - cfg80211_stop_ap(rdev, dev, -1, true); 1210 - break; 1211 - case NL80211_IFTYPE_ADHOC: 1212 - cfg80211_leave_ibss(rdev, dev, false); 1213 - break; 1214 - case NL80211_IFTYPE_STATION: 1215 - case NL80211_IFTYPE_P2P_CLIENT: 1216 - cfg80211_disconnect(rdev, dev, 1217 - WLAN_REASON_DEAUTH_LEAVING, true); 1218 - break; 1219 - case NL80211_IFTYPE_MESH_POINT: 1220 - /* mesh should be handled? */ 1221 - break; 1222 - case NL80211_IFTYPE_OCB: 1223 - cfg80211_leave_ocb(rdev, dev); 1224 - break; 1225 - default: 1226 - break; 1227 - } 1206 + cfg80211_leave(rdev, dev->ieee80211_ptr); 1228 1207 1229 1208 cfg80211_process_rdev_events(rdev); 1230 1209 cfg80211_mlme_purge_registrations(dev->ieee80211_ptr);