From 5ccdbcd797336249c959fb6f2eba0b4d657b8ef2 Mon Sep 17 00:00:00 2001 From: Josef Schlehofer <josef.schlehofer@nic.cz> Date: Fri, 14 Oct 2022 04:28:09 +0200 Subject: [PATCH] patches/openwrt: mac80211: update to version 5.15.58-1 --- .../0005-Backport-mac80211.patch | 11176 ++++++++++++---- 1 file changed, 8939 insertions(+), 2237 deletions(-) diff --git a/patches/openwrt/5.15-kernel-configuration/0005-Backport-mac80211.patch b/patches/openwrt/5.15-kernel-configuration/0005-Backport-mac80211.patch index ee86989a2..51d163429 100644 --- a/patches/openwrt/5.15-kernel-configuration/0005-Backport-mac80211.patch +++ b/patches/openwrt/5.15-kernel-configuration/0005-Backport-mac80211.patch @@ -1,22 +1,30 @@ -From 7f2c657dedb9000a984a1ecd2b30882e7a9b66bb Mon Sep 17 00:00:00 2001 +From f086537264caf27208312949dbc9ce656ecb4217 Mon Sep 17 00:00:00 2001 From: Josef Schlehofer <pepe.schlehofer@gmail.com> -Date: Mon, 23 May 2022 09:15:41 +0200 -Subject: [PATCH 5/8] Backport mac80211 +Date: Fri, 14 Oct 2022 04:25:14 +0200 +Subject: [PATCH] Backport mac80211 --- - package/kernel/mac80211/Makefile | 36 +- - package/kernel/mac80211/ath.mk | 4 +- - package/kernel/mac80211/broadcom.mk | 4 +- + package/kernel/mac80211/Makefile | 43 +- + package/kernel/mac80211/ath.mk | 7 +- + package/kernel/mac80211/broadcom.mk | 5 +- .../mac80211/files/lib/netifd/mac80211.sh | 36 - - .../files/lib/netifd/wireless/mac80211.sh | 3 +- + .../files/lib/netifd/wireless/mac80211.sh | 33 +- .../mac80211/files/lib/wifi/mac80211.sh | 5 +- + package/kernel/mac80211/intel.mk | 3 +- + package/kernel/mac80211/marvell.mk | 3 + .../patches/ath/120-owl-loader-compat.patch | 53 - .../patches/ath/402-ath_regd_optional.patch | 8 +- .../patches/ath/404-regd_no_assoc_hints.patch | 4 +- .../ath/406-ath_relax_default_regd.patch | 2 +- .../ath/550-ath9k-disable-bands-via-dt.patch | 15 - + .../ath/580-ath9k_ar9561_fix_bias_level.patch | 47 - ...h10k-increase-rx-buffer-size-to-2048.patch | 37 - - .../080-ath10k_thermal_config.patch | 0 + .../080-ath10k_thermal_config.patch | 2 +- + ...1-ath10k-improve-tx-status-reporting.patch | 69 + + ...-ath10k-turn-rawmode-into-frame-mode.patch | 74 + + ...-do-not-interpret-Eth-frames-as-WiFi.patch | 163 ++ + ...add-encapsulation-offloading-support.patch | 194 +++ + ...us-and-device-specific-API-1-BDF-sel.patch | 65 + ...calibration-data-via-nvmem-subsystem.patch | 162 ++ ...21-ath10k_init_devices_synchronously.patch | 2 +- .../930-ath10k_add_tpt_led_trigger.patch | 4 +- @@ -59,36 +67,53 @@ Subject: [PATCH 5/8] Backport mac80211 .../551-ath9k_ubnt_uap_plus_hsr.patch | 2 +- .../552-ath9k-ahb_of.patch} | 18 +- .../553-ath9k_of_gpio_mask.patch | 4 +- - .../580-ath9k_ar9561_fix_bias_level.patch | 0 ...calibration-data-via-nvmem-subsystem.patch | 154 ++ ...-fetch-pci-init-values-through-nvmem.patch | 181 +++ + ...etting-wlan-MAC-address-using-device.patch | 103 ++ .../brcm/812-b43-add-antenna-control.patch | 8 +- ...-register-wiphy-s-during-module_init.patch | 18 +- ...62-brcmfmac-Disable-power-management.patch | 2 +- ...-in-driver-tables-with-country-codes.patch | 12 +- + ...d-alternative-firmware-names-from-DT.patch | 196 +++ .../mac80211/patches/brcm/998-survey.patch | 12 +- .../build/003-remove_bogus_modparams.patch | 2 +- .../build/004-kconfig_backport_fix.patch | 28 - .../patches/build/010-disable_rfkill.patch | 15 - .../patches/build/060-no_local_ssb_bcma.patch | 18 +- + .../build/070-remove-broken-wext-select.patch | 10 + ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- + ...crease-the-global-limit-up-to-4-SSID.patch | 41 + ...940-mwl8k_init_devices_synchronously.patch | 4 +- - ...define-RF5592-in-init_eeprom-routine.patch | 2 +- - .../602-rt2x00-introduce-rt2x00eeprom.patch | 10 +- + ...ringified-name-of-command-in-error-l.patch | 189 +++ + ...define-RF5592-in-init_eeprom-routine.patch | 52 + + ...02-rt2x00-add-throughput-LED-trigger.patch | 76 + + ...define-RF5592-in-init_eeprom-routine.patch | 51 - + ...d-support-for-external-PA-on-MT7620.patch} | 72 +- + ...ove-up-and-reuse-busy-wait-functions.patch | 178 +++ + ...RF-self-TXDC-calibration-for-MT7620.patch} | 61 +- + ...rt2x00-add-r-calibration-for-MT7620.patch} | 93 +- + ...0-add-RXDCOC-calibration-for-MT7620.patch} | 62 +- + ...x00-add-RXIQ-calibration-for-MT7620.patch} | 285 ++-- + ...-run-Rt5592-IQ-calibration-on-MT7620.patch | 52 + + ...-add-TX-LOFT-calibration-for-MT7620.patch} | 277 ++-- + ...x00-move-helper-functions-up-in-file.patch | 94 ++ + ...HT20-HT40-bandwidth-switch-on-MT7620.patch | 56 + + ...t-TX_SW_CFG1-MAC-register-for-MT7620.patch | 52 + + ...t-VGC-gain-for-both-chains-of-MT7620.patch | 50 + + ...5-rt2x00-set-SoC-wmac-clock-register.patch | 70 + + ...ectly-set-BBP-register-86-for-MT7620.patch | 79 + + .../602-rt2x00-introduce-rt2x00eeprom.patch | 16 +- + .../603-rt2x00-of_load_eeprom_filename.patch | 6 +- ...isabling_bands_through_platform_data.patch | 4 +- ...07-rt2x00-add_platform_data_mac_addr.patch | 11 +- ...00-allow_disabling_bands_through_dts.patch | 2 +- ...0-rt2x00-change-led-polarity-from-OF.patch | 2 +- .../611-rt2x00-add-AP+STA-support.patch | 2 +- - .../612-rt2x00-led-tpt-trigger-support.patch | 4 +- - ...dd-support-for-external-PA-on-MT7620.patch | 6 +- - ...-rt2x00-add-rf-self-txdc-calibration.patch | 4 +- - .../rt2x00/983-rt2x00-add-r-calibration.patch | 4 +- - .../984-rt2x00-add-rxdcoc-calibration.patch | 4 +- - .../985-rt2x00-add-rxiq-calibration.patch | 4 +- - .../986-rt2x00-add-TX-LOFT-calibration.patch | 4 +- - ...-differentiate-based-on-SoC-CHIP_VER.patch | 16 +- + .../612-rt2x00-led-tpt-trigger-support.patch | 44 - ...ave-survey-for-every-channel-visited.patch | 183 --- + ...t-support-for-external-LNA-on-MT7620.patch | 161 ++ + ...uce-accessors-for-CHIP_VER-register.patch} | 0 + ...differentiate-based-on-SoC-CHIP_VER.patch} | 28 +- ...ent-set_tim-by-update-beacon-content.patch | 118 -- .../patches/subsys/010-sync-nl80211_h.patch | 297 ---- .../100-remove-cryptoapi-dependencies.patch | 699 --------- @@ -108,9 +133,9 @@ Subject: [PATCH 5/8] Backport mac80211 ...211_hwsim-make-6-GHz-channels-usable.patch | 74 + ...d-support-for-.ndo_fill_forward_path.patch | 178 +++ ...minstrel_ht-fix-MINSTREL_FRAC-macro.patch} | 0 - ..._ht-reduce-fluctuations-in-rate-pro.patch} | 0 + ..._ht-reduce-fluctuations-in-rate-pro.patch} | 2 +- ...-free-packets-from-a-flow-on-overmem.patch | 95 -- - ..._ht-rework-rate-downgrade-code-and-.patch} | 10 +- + ..._ht-rework-rate-downgrade-code-and-.patch} | 16 +- ...-get_default_func-move-default-flow-.patch | 144 -- ...211-split-beacon-retrieval-functions.patch | 262 ++++ ...ot-maintain-a-backlog-sorted-list-of.patch | 317 ---- @@ -128,23 +153,42 @@ Subject: [PATCH 5/8] Backport mac80211 ...11-MBSSID-beacon-handling-in-AP-mode.patch | 326 ++++ .../325-mac80211-MBSSID-channel-switch.patch | 52 + ...bssid_indicator-in-ieee80211_assign_.patch | 25 + - ...l_ht-fix-where-rate-stats-are-stored.patch | 61 + + ...wake-queues-on-a-vif-that-is-being-s.patch | 38 + + ...airtime-fairness-back-to-deficit-rou.patch | 1249 ++++++++++++++++ + ...a-airtime-deficit-field-s32-instead-.patch | 52 + + ...r-aql_tx_pending-when-checking-airti.patch | 48 + + ...cently-active-tx-queues-in-schedulin.patch | 118 ++ + ...er-PHY-AQL-limit-to-improve-fairness.patch | 131 ++ + ...ugfs-file-to-display-per-phy-AQL-pen.patch | 58 + + ...cumulate-airtime-deficit-for-active-.patch | 36 + + ...crease-quantum-for-airtime-scheduler.patch | 53 + ...c80211-minstrel_ht-clean-up-CCK-code.patch | 166 --- ...l_ht-add-support-for-OFDM-rates-on-n.patch | 762 ---------- + ...-multicast-packets-from-AQL-pending-.patch | 30 + ...-remove-legacy-minstrel-rate-control.patch | 1328 ----------------- ...l_ht-remove-old-ewma-based-rate-aver.patch | 96 -- + ...-not-abuse-fq.lock-in-ieee80211_do_s.patch | 46 + + ...dlock-Don-t-start-TX-while-holding-f.patch | 40 + ...l_ht-improve-ampdu-length-estimation.patch | 67 - + ...vif-queues-are-operational-after-sta.patch | 47 + ...rel_ht-improve-sample-rate-selection.patch | 31 - ...l_ht-fix-max-probability-rate-select.patch | 124 -- + ...x-decap-offload-for-stations-on-AP_V.patch | 37 + ...el_ht-increase-stats-update-interval.patch | 20 - + ...x-ieee80211_data_to_8023_exthdr-hand.patch | 99 ++ ...l_ht-fix-rounding-error-in-throughpu.patch | 34 - + ...-not-drop-packets-smaller-than-the-L.patch | 25 + ...l_ht-use-bitfields-to-encode-rate-in.patch | 412 ----- ...l_ht-update-total-packets-counter-in.patch | 54 - ...l_ht-reduce-the-need-to-sample-slowe.patch | 102 -- ...l_ht-significantly-redesign-the-rate.patch | 767 ---------- + .../subsys/350-bss-color-collision.patch | 118 ++ ...el_ht-show-sampling-rates-in-debugfs.patch | 58 - ...l_ht-remove-sample-rate-switching-co.patch | 279 ---- ...l_ht-fix-regression-in-the-max_prob_.patch | 23 - + ...emory-leak-where-sta_info-is-not-fre.patch | 77 + + ...n-t-finalize-CSA-in-IBSS-mode-if-sta.patch | 47 + + ...ac80211-Fix-UAF-in-ieee80211_scan_rx.patch | 55 + ...pply-flow-control-on-management-fram.patch | 60 - ...set-sk_pacing_shift-for-802.3-txpath.patch | 21 - ...-Rx-timestamp-calculation-for-all-pr.patch | 134 -- @@ -167,16 +211,26 @@ Subject: [PATCH 5/8] Backport mac80211 ...pelling-of-A-MSDU-in-HE-capabilities.patch | 113 -- ...E-capabilities-A-MPDU-Length-Exponen.patch | 148 -- ...ate-control-for-retransmitted-frames.patch | 35 - + ...x-crash-in-beacon-protection-for-P2P.patch | 52 - + .../patches/subsys/397-disable-mbssid.patch | 44 - .../patches/subsys/400-allow-ibss-mixed.patch | 2 +- .../500-mac80211_configure_antenna_gain.patch | 66 +- ...the-dst-buffer-to-of_get_mac_address.patch | 29 + + .../patches/subsys/783-sync-nl80211.patch | 22 + + ...-mask-nested-A-MSDU-support-for-mesh.patch | 33 + package/kernel/mac80211/realtek.mk | 18 + - 167 files changed, 4074 insertions(+), 12997 deletions(-) + 215 files changed, 9043 insertions(+), 13587 deletions(-) delete mode 100644 package/kernel/mac80211/files/lib/netifd/mac80211.sh delete mode 100644 package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch delete mode 100644 package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch + delete mode 100644 package/kernel/mac80211/patches/ath/580-ath9k_ar9561_fix_bias_level.patch delete mode 100644 package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch - rename package/kernel/mac80211/patches/{ath => ath10k}/080-ath10k_thermal_config.patch (100%) + rename package/kernel/mac80211/patches/{ath => ath10k}/080-ath10k_thermal_config.patch (97%) + create mode 100644 package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch + create mode 100644 package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch + create mode 100644 package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch + create mode 100644 package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch + create mode 100644 package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch create mode 100644 package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch rename package/kernel/mac80211/patches/{ath => ath10k}/921-ath10k_init_devices_synchronously.patch (94%) rename package/kernel/mac80211/patches/{ath => ath10k}/930-ath10k_add_tpt_led_trigger.patch (89%) @@ -219,12 +273,37 @@ Subject: [PATCH 5/8] Backport mac80211 rename package/kernel/mac80211/patches/{ath => ath9k}/551-ath9k_ubnt_uap_plus_hsr.patch (99%) rename package/kernel/mac80211/patches/{ath/552-ahb_of.patch => ath9k/552-ath9k-ahb_of.patch} (93%) rename package/kernel/mac80211/patches/{ath => ath9k}/553-ath9k_of_gpio_mask.patch (80%) - rename package/kernel/mac80211/patches/{ath => ath9k}/580-ath9k_ar9561_fix_bias_level.patch (100%) create mode 100644 package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch create mode 100644 package/kernel/mac80211/patches/ath9k/601-v5.16-ath9k-owl-loader-fetch-pci-init-values-through-nvmem.patch + create mode 100644 package/kernel/mac80211/patches/brcm/001-brcmfmac-allow-setting-wlan-MAC-address-using-device.patch + create mode 100644 package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch delete mode 100644 package/kernel/mac80211/patches/build/004-kconfig_backport_fix.patch delete mode 100644 package/kernel/mac80211/patches/build/010-disable_rfkill.patch + create mode 100644 package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch + create mode 100644 package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch + create mode 100644 package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/001-rt2x00-define-RF5592-in-init_eeprom-routine.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/002-rt2x00-add-throughput-LED-trigger.patch + delete mode 100644 package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch + rename package/kernel/mac80211/patches/rt2x00/{650-rt2x00-add-support-for-external-PA-on-MT7620.patch => 003-rt2x00-add-support-for-external-PA-on-MT7620.patch} (58%) + create mode 100644 package/kernel/mac80211/patches/rt2x00/004-rt2x00-move-up-and-reuse-busy-wait-functions.patch + rename package/kernel/mac80211/patches/rt2x00/{982-rt2x00-add-rf-self-txdc-calibration.patch => 005-rt2x00-add-RF-self-TXDC-calibration-for-MT7620.patch} (51%) + rename package/kernel/mac80211/patches/rt2x00/{983-rt2x00-add-r-calibration.patch => 006-rt2x00-add-r-calibration-for-MT7620.patch} (66%) + rename package/kernel/mac80211/patches/rt2x00/{984-rt2x00-add-rxdcoc-calibration.patch => 007-rt2x00-add-RXDCOC-calibration-for-MT7620.patch} (50%) + rename package/kernel/mac80211/patches/rt2x00/{985-rt2x00-add-rxiq-calibration.patch => 008-rt2x00-add-RXIQ-calibration-for-MT7620.patch} (63%) + create mode 100644 package/kernel/mac80211/patches/rt2x00/009-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch + rename package/kernel/mac80211/patches/rt2x00/{986-rt2x00-add-TX-LOFT-calibration.patch => 010-rt2x00-add-TX-LOFT-calibration-for-MT7620.patch} (84%) + create mode 100644 package/kernel/mac80211/patches/rt2x00/011-rt2x00-move-helper-functions-up-in-file.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/012-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/013-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT7620.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/014-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/015-rt2x00-set-SoC-wmac-clock-register.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/016-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch + delete mode 100644 package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch delete mode 100644 package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch + create mode 100644 package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch + rename package/kernel/mac80211/patches/rt2x00/{990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch => 995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch} (100%) + rename package/kernel/mac80211/patches/rt2x00/{991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch => 996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch} (95%) delete mode 100644 package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch delete mode 100644 package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch delete mode 100644 package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch @@ -240,9 +319,9 @@ Subject: [PATCH 5/8] Backport mac80211 create mode 100644 package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch create mode 100644 package/kernel/mac80211/patches/subsys/308-mac80211-add-support-for-.ndo_fill_forward_path.patch rename package/kernel/mac80211/patches/subsys/{353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch => 309-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch} (100%) - rename package/kernel/mac80211/patches/subsys/{354-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch => 310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch} (100%) + rename package/kernel/mac80211/patches/subsys/{354-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch => 310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch} (94%) delete mode 100644 package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch - rename package/kernel/mac80211/patches/subsys/{355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch => 311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch} (93%) + rename package/kernel/mac80211/patches/subsys/{355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch => 311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch} (90%) delete mode 100644 package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch create mode 100644 package/kernel/mac80211/patches/subsys/312-mac80211-split-beacon-retrieval-functions.patch delete mode 100644 package/kernel/mac80211/patches/subsys/312-net-fq_impl-do-not-maintain-a-backlog-sorted-list-of.patch @@ -260,23 +339,42 @@ Subject: [PATCH 5/8] Backport mac80211 create mode 100644 package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch create mode 100644 package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch create mode 100644 package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch - create mode 100644 package/kernel/mac80211/patches/subsys/329-mac80211-minstrel_ht-fix-where-rate-stats-are-stored.patch + create mode 100644 package/kernel/mac80211/patches/subsys/328-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch + create mode 100644 package/kernel/mac80211/patches/subsys/330-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch + create mode 100644 package/kernel/mac80211/patches/subsys/331-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch + create mode 100644 package/kernel/mac80211/patches/subsys/332-mac80211-consider-aql_tx_pending-when-checking-airti.patch + create mode 100644 package/kernel/mac80211/patches/subsys/333-mac80211-keep-recently-active-tx-queues-in-schedulin.patch + create mode 100644 package/kernel/mac80211/patches/subsys/334-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch + create mode 100644 package/kernel/mac80211/patches/subsys/335-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch + create mode 100644 package/kernel/mac80211/patches/subsys/336-mac80211-only-accumulate-airtime-deficit-for-active-.patch + create mode 100644 package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch delete mode 100644 package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch delete mode 100644 package/kernel/mac80211/patches/subsys/338-mac80211-minstrel_ht-add-support-for-OFDM-rates-on-n.patch + create mode 100644 package/kernel/mac80211/patches/subsys/339-mac80211-exclude-multicast-packets-from-AQL-pending-.patch delete mode 100644 package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch delete mode 100644 package/kernel/mac80211/patches/subsys/340-mac80211-minstrel_ht-remove-old-ewma-based-rate-aver.patch + create mode 100644 package/kernel/mac80211/patches/subsys/340-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch + create mode 100644 package/kernel/mac80211/patches/subsys/341-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch delete mode 100644 package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch + create mode 100644 package/kernel/mac80211/patches/subsys/342-mac80211-Ensure-vif-queues-are-operational-after-sta.patch delete mode 100644 package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch delete mode 100644 package/kernel/mac80211/patches/subsys/343-mac80211-minstrel_ht-fix-max-probability-rate-select.patch + create mode 100644 package/kernel/mac80211/patches/subsys/343-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch delete mode 100644 package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch + create mode 100644 package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch delete mode 100644 package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch + create mode 100644 package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch delete mode 100644 package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch delete mode 100644 package/kernel/mac80211/patches/subsys/347-mac80211-minstrel_ht-update-total-packets-counter-in.patch delete mode 100644 package/kernel/mac80211/patches/subsys/348-mac80211-minstrel_ht-reduce-the-need-to-sample-slowe.patch delete mode 100644 package/kernel/mac80211/patches/subsys/349-mac80211-minstrel_ht-significantly-redesign-the-rate.patch + create mode 100644 package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch delete mode 100644 package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch delete mode 100644 package/kernel/mac80211/patches/subsys/351-mac80211-minstrel_ht-remove-sample-rate-switching-co.patch delete mode 100644 package/kernel/mac80211/patches/subsys/352-mac80211-minstrel_ht-fix-regression-in-the-max_prob_.patch + create mode 100644 package/kernel/mac80211/patches/subsys/360-mac80211-fix-a-memory-leak-where-sta_info-is-not-fre.patch + create mode 100644 package/kernel/mac80211/patches/subsys/361-wifi-mac80211-Don-t-finalize-CSA-in-IBSS-mode-if-sta.patch + create mode 100644 package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch delete mode 100644 package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch delete mode 100644 package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch delete mode 100644 package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch @@ -299,10 +397,14 @@ Subject: [PATCH 5/8] Backport mac80211 delete mode 100644 package/kernel/mac80211/patches/subsys/392-wireless-fix-spelling-of-A-MSDU-in-HE-capabilities.patch delete mode 100644 package/kernel/mac80211/patches/subsys/393-wireless-align-HE-capabilities-A-MPDU-Length-Exponen.patch delete mode 100644 package/kernel/mac80211/patches/subsys/394-mac80211-fix-rate-control-for-retransmitted-frames.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/396-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch + delete mode 100644 package/kernel/mac80211/patches/subsys/397-disable-mbssid.patch create mode 100644 package/kernel/mac80211/patches/subsys/782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch + create mode 100644 package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch + create mode 100644 package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -index d92d4f5457..e51208aaba 100644 +index d92d4f5457..44428ca89f 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk @@ -310,12 +412,13 @@ index d92d4f5457..e51208aaba 100644 PKG_NAME:=mac80211 -PKG_VERSION:=5.10.110-1 -+PKG_VERSION:=5.15.33-1 - PKG_RELEASE:=1 +-PKG_RELEASE:=1 -PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.110/ -PKG_HASH:=3d958154080c059adaf26512430fd1a8888d65a2228e5e70e48d028201e148b1 -+PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.33/ -+PKG_HASH:=1b6b3bded4c81814ebebe2d194c2f8966d2399005b85ebb0557285b6e73f5422 ++PKG_VERSION:=5.15.58-1 ++PKG_RELEASE:=2 ++PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/ ++PKG_HASH:=a3c2a2b7bbaf8943c65fd72f4e7d7ad5e205aeae28b26c835f9d8afa0f9810bf PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) @@ -327,7 +430,15 @@ index d92d4f5457..e51208aaba 100644 hermes hermes-pci hermes-pcmcia hermes-plx\ lib80211 \ mac80211-hwsim \ -@@ -98,7 +97,7 @@ PKG_CONFIG_DEPENDS += \ +@@ -57,7 +56,6 @@ config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m) + + config-y:= \ + WLAN \ +- CFG80211_WEXT \ + CFG80211_CERTIFICATION_ONUS \ + MAC80211_RC_MINSTREL \ + MAC80211_RC_MINSTREL_HT \ +@@ -98,7 +96,7 @@ PKG_CONFIG_DEPENDS += \ define KernelPackage/cfg80211 $(call KernelPackage/mac80211/Default) TITLE:=cfg80211 - wireless configuration API @@ -336,7 +447,7 @@ index d92d4f5457..e51208aaba 100644 ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) FILES:= \ $(PKG_BUILD_DIR)/compat/compat.ko \ -@@ -127,7 +126,7 @@ define KernelPackage/mac80211 +@@ -127,7 +125,7 @@ define KernelPackage/mac80211 $(call KernelPackage/mac80211/Default) TITLE:=Linux 802.11 Wireless Networking Stack # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c @@ -345,7 +456,7 @@ index d92d4f5457..e51208aaba 100644 KCONFIG:=\ CONFIG_AVERAGE=y FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko -@@ -174,18 +173,6 @@ define KernelPackage/adm8211 +@@ -174,22 +172,11 @@ define KernelPackage/adm8211 AUTOLOAD:=$(call AutoProbe,adm8211) endef @@ -364,7 +475,29 @@ index d92d4f5457..e51208aaba 100644 define KernelPackage/hermes $(call KernelPackage/mac80211/Default) TITLE:=Hermes 802.11b chipset support -@@ -406,8 +393,6 @@ endif + DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT +kmod-crypto-michael-mic ++ DEFAULT:=n + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco.ko + AUTOLOAD:=$(call AutoProbe,orinoco) + endef +@@ -239,6 +226,7 @@ define KernelPackage/lib80211 + $(call KernelPackage/mac80211/Default) + TITLE:=802.11 Networking stack + DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash +kmod-crypto-ccm ++ HIDDEN:=1 + FILES:= \ + $(PKG_BUILD_DIR)/net/wireless/lib80211.ko \ + $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \ +@@ -265,7 +253,7 @@ endef + define KernelPackage/mac80211-hwsim + $(call KernelPackage/mac80211/Default) + TITLE:=mac80211 HW simulation device +- DEPENDS+= +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT ++ DEPENDS+= +kmod-mac80211 +@DRIVER_11AX_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko + AUTOLOAD:=$(call AutoProbe,mac80211_hwsim) + endef +@@ -406,8 +394,6 @@ endif config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP @@ -373,7 +506,7 @@ index d92d4f5457..e51208aaba 100644 config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM config-$(call config_package,mt7601u) += MT7601U config-y += WL_MEDIATEK -@@ -507,9 +492,14 @@ define Build/Patch +@@ -507,9 +493,14 @@ define Build/Patch $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) @@ -388,7 +521,7 @@ index d92d4f5457..e51208aaba 100644 $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) endef -@@ -517,9 +507,14 @@ define Quilt/Refresh/Package +@@ -517,9 +508,14 @@ define Quilt/Refresh/Package $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/) @@ -403,7 +536,7 @@ index d92d4f5457..e51208aaba 100644 endef define Build/Compile -@@ -545,7 +540,6 @@ endef +@@ -545,7 +541,6 @@ endef define KernelPackage/cfg80211/install $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi @@ -412,7 +545,7 @@ index d92d4f5457..e51208aaba 100644 $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk -index e815f37e1c..50b1eed9c8 100644 +index e815f37e1c..9af8c4665d 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -34,7 +34,7 @@ ifdef CONFIG_PACKAGE_MAC80211_TRACING @@ -433,8 +566,18 @@ index e815f37e1c..50b1eed9c8 100644 config-$(CONFIG_ATH9K_HWRNG) += ATH9K_HWRNG config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 +@@ -260,7 +260,8 @@ define KernelPackage/ath10k + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko +- AUTOLOAD:=$(call AutoProbe,ath10k_pci) ++ AUTOLOAD:=$(call AutoProbe,ath10k_core ath10k_pci) ++ MODPARAMS.ath10k_core:=frame_mode=2 + VARIANT:=regular + endef + diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk -index fb576c5809..473bbf597c 100644 +index fb576c5809..5548f6e661 100644 --- a/package/kernel/mac80211/broadcom.mk +++ b/package/kernel/mac80211/broadcom.mk @@ -209,7 +209,7 @@ config PACKAGE_B43_USE_BCMA @@ -455,6 +598,14 @@ index fb576c5809..473bbf597c 100644 A => A-PHY AG => Dual A-PHY G-PHY G => G-PHY +@@ -450,6 +450,7 @@ define KernelPackage/brcmfmac/config + config BRCMFMAC_SDIO + bool "Enable SDIO bus interface support" + default y if TARGET_bcm27xx ++ default y if TARGET_imx_cortexa7 + default y if TARGET_sunxi + default n + help diff --git a/package/kernel/mac80211/files/lib/netifd/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/mac80211.sh deleted file mode 100644 index 92e5c0e395..0000000000 @@ -498,18 +649,84 @@ index 92e5c0e395..0000000000 - done -} diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -index d69667bf8c..27eecf3a7f 100644 +index d69667bf8c..f462fc8ad9 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -@@ -1,7 +1,6 @@ +@@ -1,7 +1,7 @@ #!/bin/sh . /lib/netifd/netifd-wireless.sh . /lib/netifd/hostapd.sh -. /lib/netifd/mac80211.sh ++. /lib/functions/system.sh init_wireless_driver "$@" -@@ -563,7 +562,7 @@ mac80211_generate_mac() { +@@ -29,8 +29,8 @@ drv_mac80211_init_device_config() { + config_add_string tx_burst + config_add_string distance + config_add_int beacon_int chanbw frag rts +- config_add_int rxantenna txantenna antenna_gain txpower +- config_add_boolean noscan ht_coex acs_exclude_dfs ++ config_add_int rxantenna txantenna antenna_gain txpower min_tx_power ++ config_add_boolean noscan ht_coex acs_exclude_dfs background_radar + config_add_array ht_capab + config_add_array channels + config_add_array scan_list +@@ -138,13 +138,15 @@ mac80211_hostapd_setup_base() { + [ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && + append base_cfg "acs_exclude_dfs=1" "$N" + +- json_get_vars noscan ht_coex +- json_get_values ht_capab_list ht_capab tx_burst ++ json_get_vars noscan ht_coex min_tx_power:0 tx_burst ++ json_get_values ht_capab_list ht_capab + json_get_values channel_list channels + + [ "$auto_channel" = 0 ] && [ -z "$channel_list" ] && \ + channel_list="$channel" + ++ [ "$min_tx_power" -gt 0 ] && append base_cfg "min_tx_power=$min_tx_power" ++ + set_default noscan 0 + + [ "$noscan" -gt 0 ] && hostapd_noscan=1 +@@ -274,6 +276,11 @@ mac80211_hostapd_setup_base() { + vht_center_seg0=$idx + ;; + esac ++ [ "$band" = "5g" ] && { ++ json_get_vars background_radar:0 ++ ++ [ "$background_radar" -eq 1 ] && append base_cfg "enable_background_radar=1" "$N" ++ } + [ "$band" = "6g" ] && { + op_class= + case "$htmode" in +@@ -414,18 +421,20 @@ mac80211_hostapd_setup_base() { + he_spr_non_srg_obss_pd_max_offset:1 \ + he_bss_color + +- he_phy_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) ++ he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) + he_phy_cap=${he_phy_cap:2} +- he_mac_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) ++ he_mac_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1) + he_mac_cap=${he_mac_cap:2} + + append base_cfg "ieee80211ax=1" "$N" +- [ -n "$he_bss_color" ] && append base_cfg "he_bss_color=$he_bss_color" "$N" + [ "$hwmode" = "a" ] && { + append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N" + append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" + } + ++ set_default he_bss_color 128 ++ append base_cfg "he_bss_color=$he_bss_color" "$N" ++ + mac80211_add_he_capabilities \ + he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \ + he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \ +@@ -563,7 +572,7 @@ mac80211_generate_mac() { find_phy() { [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 [ -n "$path" ] && { @@ -518,6 +735,21 @@ index d69667bf8c..27eecf3a7f 100644 [ -n "$phy" ] && return 0 } [ -n "$macaddr" ] && { +@@ -659,10 +668,12 @@ mac80211_prepare_vif() { + + json_select .. + +- [ -n "$macaddr" ] || { ++ if [ -z "$macaddr" ]; then + macaddr="$(mac80211_generate_mac $phy)" + macidx="$(($macidx + 1))" +- } ++ elif [ "$macaddr" = 'random' ]; then ++ macaddr="$(macaddr_random)" ++ fi + + json_add_object data + json_add_string ifname "$ifname" diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index 5eb7cc4c61..6aa46b0c74 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -546,6 +778,55 @@ index 5eb7cc4c61..6aa46b0c74 100644 if [ -n "$path" ]; then dev_id="set wireless.radio${devidx}.path='$path'" else +diff --git a/package/kernel/mac80211/intel.mk b/package/kernel/mac80211/intel.mk +index 8bab727a41..eca4a574be 100644 +--- a/package/kernel/mac80211/intel.mk ++++ b/package/kernel/mac80211/intel.mk +@@ -15,7 +15,7 @@ config-$(call config_package,ipw2200) += IPW2200 + + define KernelPackage/iwlwifi + $(call KernelPackage/mac80211/Default) +- DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT ++ DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT + TITLE:=Intel AGN Wireless support + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ +@@ -125,6 +125,7 @@ define KernelPackage/libipw + $(call KernelPackage/mac80211/Default) + TITLE:=libipw for ipw2100 and ipw2200 + DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-crypto-ecb +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN ++ DEFAULT:=n + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/libipw.ko + AUTOLOAD:=$(call AutoProbe,libipw) + endef +diff --git a/package/kernel/mac80211/marvell.mk b/package/kernel/mac80211/marvell.mk +index a0e67091e5..254395932d 100644 +--- a/package/kernel/mac80211/marvell.mk ++++ b/package/kernel/mac80211/marvell.mk +@@ -13,6 +13,7 @@ define KernelPackage/libertas-usb + $(call KernelPackage/mac80211/Default) + DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware + TITLE:=Marvell 88W8015 Wireless Driver ++ DEFAULT:=n + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/usb8xxx.ko +@@ -23,6 +24,7 @@ define KernelPackage/libertas-sdio + $(call KernelPackage/mac80211/Default) + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware + TITLE:=Marvell 88W8686 Wireless Driver ++ DEFAULT:=n + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_sdio.ko +@@ -33,6 +35,7 @@ define KernelPackage/libertas-spi + $(call KernelPackage/mac80211/Default) + SUBMENU:=Wireless Drivers + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware ++ DEFAULT:=n + KCONFIG := \ + CONFIG_SPI=y \ + CONFIG_SPI_MASTER=y diff --git a/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch b/package/kernel/mac80211/patches/ath/120-owl-loader-compat.patch deleted file mode 100644 index d1d6c9e2e3..0000000000 @@ -606,7 +887,7 @@ index d1d6c9e2e3..0000000000 - - eeprom_name = devm_kzalloc(dev, EEPROM_FILENAME_LEN, GFP_KERNEL); diff --git a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch -index bf87d3551a..514cfd9e5e 100644 +index bf87d3551a..4ea33365d1 100644 --- a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch +++ b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch @@ -37,7 +37,7 @@ @@ -641,19 +922,19 @@ index bf87d3551a..514cfd9e5e 100644 --- a/local-symbols +++ b/local-symbols -@@ -85,6 +85,7 @@ ADM8211= -+@@ -83,6 +83,7 @@ ADM8211= ++@@ -106,6 +106,7 @@ ADM8211= ATH_COMMON= WLAN_VENDOR_ATH= ATH_DEBUG= diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch -index c6dc184e28..c8eef504c6 100644 +index c6dc184e28..02281adf4a 100644 --- a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch +++ b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch @@ -1,6 +1,6 @@ --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -3252,6 +3252,8 @@ void regulatory_hint_country_ie(struct w -+@@ -3304,6 +3304,8 @@ void regulatory_hint_country_ie(struct w ++@@ -3309,6 +3309,8 @@ void regulatory_hint_country_ie(struct w enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request = NULL, *lr; @@ -662,7 +943,7 @@ index c6dc184e28..c8eef504c6 100644 if (country_ie_len & 0x01) return; -@@ -3503,6 +3505,7 @@ static bool is_wiphy_all_set_reg_flag(en -+@@ -3555,6 +3557,7 @@ static bool is_wiphy_all_set_reg_flag(en ++@@ -3560,6 +3562,7 @@ static bool is_wiphy_all_set_reg_flag(en void regulatory_hint_disconnect(void) { @@ -700,6 +981,59 @@ index 7d3a334c42..0000000000 - if (of_property_read_bool(np, "qca,no-eeprom")) { - /* ath9k-eeprom-<bus>-<id>.bin */ - scnprintf(eeprom_name, sizeof(eeprom_name), +diff --git a/package/kernel/mac80211/patches/ath/580-ath9k_ar9561_fix_bias_level.patch b/package/kernel/mac80211/patches/ath/580-ath9k_ar9561_fix_bias_level.patch +deleted file mode 100644 +index e4c2e1cd02..0000000000 +--- a/package/kernel/mac80211/patches/ath/580-ath9k_ar9561_fix_bias_level.patch ++++ /dev/null +@@ -1,47 +0,0 @@ +-From 4509e523dba46f789377cfec6f20579adf743416 Mon Sep 17 00:00:00 2001 +-From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks+kernel@slashdirt.org> +-Date: Sun, 17 Apr 2022 11:31:35 +0200 +-Subject: [PATCH v2] ath9k: fix QCA9561 PA bias level +-MIME-Version: 1.0 +-Content-Type: text/plain; charset=UTF-8 +-Content-Transfer-Encoding: 8bit +- +-This patch fixes an invalid TX PA DC bias level on QCA9561, which +-results in a very low output power and very low throughput as devices +-are further away from the AP (compared to other 2.4GHz APs). +- +-This patch was suggested by Felix Fietkau, who noted[1]: +-"The value written to that register is wrong, because while the mask +-definition AR_CH0_TOP2_XPABIASLVL uses a different value for 9561, the +-shift definition AR_CH0_TOP2_XPABIASLVL_S is hardcoded to 12, which is +-wrong for 9561." +- +-In real life testing, without this patch the 2.4GHz throughput on +-Yuncore XD3200 is around 10Mbps sitting next to the AP, and closer to +-practical maximum with the patch applied. +- +-[1] https://lore.kernel.org/all/91c58969-c60e-2f41-00ac-737786d435ae@nbd.name +- +-Signed-off-by: Thibaut VARÈNE <hacks+kernel@slashdirt.org> +---- +-v2: Adjust #define per Felix's suggestion +---- +- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 +- +- 1 file changed, 1 insertion(+), 1 deletion(-) +- +-diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h +-index a171dbb29..ad949eb02 100644 +---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h +-@@ -720,7 +720,7 @@ +- #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ +- (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) +- #define AR_CH0_TOP2_XPABIASLVL (AR_SREV_9561(ah) ? 0x1e00 : 0xf000) +--#define AR_CH0_TOP2_XPABIASLVL_S 12 +-+#define AR_CH0_TOP2_XPABIASLVL_S (AR_SREV_9561(ah) ? 9 : 12) +- +- #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ +- ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : \ +--- +-2.30.2 +- diff --git a/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch b/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch deleted file mode 100644 index 8f7a60eec8..0000000000 @@ -744,12 +1078,619 @@ index 8f7a60eec8..0000000000 - - /* Refill a bunch of RX buffers for each refill round so that FW/HW can handle diff --git a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch -similarity index 100% +similarity index 97% rename from package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch rename to package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch +index de6f9d9bb0..d9a3cd534c 100644 +--- a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch ++++ b/package/kernel/mac80211/patches/ath10k/080-ath10k_thermal_config.patch +@@ -37,7 +37,7 @@ + void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); + --- a/local-symbols + +++ b/local-symbols +-@@ -142,6 +142,7 @@ ATH10K_SNOC= ++@@ -165,6 +165,7 @@ ATH10K_SNOC= + ATH10K_DEBUG= + ATH10K_DEBUGFS= + ATH10K_SPECTRAL= +diff --git a/package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch b/package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch +new file mode 100644 +index 0000000000..c024850918 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/081-01-ath10k-improve-tx-status-reporting.patch +@@ -0,0 +1,69 @@ ++From 2587d5198aa5adcbd8896aae4a2404dc13d48637 Mon Sep 17 00:00:00 2001 ++From: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Date: Wed, 18 May 2022 10:27:26 +0300 ++Subject: ath10k: improve tx status reporting ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++We use ieee80211_tx_status() to report each completed tx frame. ++Internally, this function calls sta_info_get_by_addrs(), what has a ++couple of drawbacks: ++1. additional station lookup causes a performance degradation; ++2. mac80211 can not properly account Ethernet encapsulated frames due ++ to the inability to properly determine the destination (station) MAC ++ address since ieee80211_tx_status() assumes the frame has a 802.11 ++ header. ++ ++The latter is especially destructive if we want to use hardware frames ++encapsulation. ++ ++To fix both of these issues, replace ieee80211_tx_status() with ++ieee80211_tx_status_ext() call and feed it station pointer from the tx ++queue associated with the transmitted frame. ++ ++Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131 ++Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1 ++ ++Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Tested-by: OldÅ™ich JedliÄka <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880) ++Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1) ++Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode ++Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159) ++Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> ++Link: https://lore.kernel.org/r/20220516032519.29831-2-ryazanov.s.a@gmail.com ++--- ++ drivers/net/wireless/ath/ath10k/txrx.c | 15 ++++++++++++++- ++ 1 file changed, 14 insertions(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ath/ath10k/txrx.c +++++ b/drivers/net/wireless/ath/ath10k/txrx.c ++@@ -43,6 +43,7 @@ out: ++ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, ++ const struct htt_tx_done *tx_done) ++ { +++ struct ieee80211_tx_status status; ++ struct ath10k *ar = htt->ar; ++ struct device *dev = ar->dev; ++ struct ieee80211_tx_info *info; ++@@ -128,7 +129,19 @@ int ath10k_txrx_tx_unref(struct ath10k_h ++ info->status.is_valid_ack_signal = true; ++ } ++ ++- ieee80211_tx_status(htt->ar->hw, msdu); +++ memset(&status, 0, sizeof(status)); +++ status.skb = msdu; +++ status.info = info; +++ +++ rcu_read_lock(); +++ +++ if (txq) +++ status.sta = txq->sta; +++ +++ ieee80211_tx_status_ext(htt->ar->hw, &status); +++ +++ rcu_read_unlock(); +++ ++ /* we do not own the msdu anymore */ ++ ++ return 0; +diff --git a/package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch b/package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch +new file mode 100644 +index 0000000000..e672815522 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/081-02-ath10k-turn-rawmode-into-frame-mode.patch +@@ -0,0 +1,74 @@ ++From a09740548275a74b897654b3aca5af589289b57a Mon Sep 17 00:00:00 2001 ++From: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Date: Mon, 16 May 2022 13:26:00 +0300 ++Subject: ath10k: turn rawmode into frame_mode ++ ++Turn boolean rawmode module param into integer frame_mode param that ++contains value from ath10k_hw_txrx_mode enum. As earlier the default ++param value is non-RAW (native Wi-Fi) encapsulation. The param name ++is selected to be consistent with the similar ath11k param. ++ ++This is a preparation step for upcoming encapsulation offloading ++support. ++ ++Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> ++Link: https://lore.kernel.org/r/20220516032519.29831-4-ryazanov.s.a@gmail.com ++--- ++ drivers/net/wireless/ath/ath10k/core.c | 11 +++++++---- ++ drivers/net/wireless/ath/ath10k/core.h | 1 + ++ 2 files changed, 8 insertions(+), 4 deletions(-) ++ ++--- a/drivers/net/wireless/ath/ath10k/core.c +++++ b/drivers/net/wireless/ath/ath10k/core.c ++@@ -32,9 +32,11 @@ EXPORT_SYMBOL(ath10k_debug_mask); ++ static unsigned int ath10k_cryptmode_param; ++ static bool uart_print; ++ static bool skip_otp; ++-static bool rawmode; ++ static bool fw_diag_log; ++ +++/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */ +++unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI; +++ ++ unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) | ++ BIT(ATH10K_FW_CRASH_DUMP_CE_DATA); ++ ++@@ -43,15 +45,16 @@ module_param_named(debug_mask, ath10k_de ++ module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644); ++ module_param(uart_print, bool, 0644); ++ module_param(skip_otp, bool, 0644); ++-module_param(rawmode, bool, 0644); ++ module_param(fw_diag_log, bool, 0644); +++module_param_named(frame_mode, ath10k_frame_mode, uint, 0644); ++ module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444); ++ ++ MODULE_PARM_DESC(debug_mask, "Debugging mask"); ++ MODULE_PARM_DESC(uart_print, "Uart target debugging"); ++ MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); ++ MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software"); ++-MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath"); +++MODULE_PARM_DESC(frame_mode, +++ "Datapath frame mode (0: raw, 1: native wifi (default))"); ++ MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); ++ MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); ++ ++@@ -2487,7 +2490,7 @@ static int ath10k_core_init_firmware_fea ++ ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT; ++ ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT; ++ ++- if (rawmode) { +++ if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) { ++ if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT, ++ fw_file->fw_features)) { ++ ath10k_err(ar, "rawmode = 1 requires support from firmware"); ++--- a/drivers/net/wireless/ath/ath10k/core.h +++++ b/drivers/net/wireless/ath/ath10k/core.h ++@@ -1311,6 +1311,7 @@ static inline bool ath10k_peer_stats_ena ++ return false; ++ } ++ +++extern unsigned int ath10k_frame_mode; ++ extern unsigned long ath10k_coredump_mask; ++ ++ void ath10k_core_napi_sync_disable(struct ath10k *ar); +diff --git a/package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch b/package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch +new file mode 100644 +index 0000000000..a669c77fe2 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/081-03-ath10k-htt-tx-do-not-interpret-Eth-frames-as-WiFi.patch +@@ -0,0 +1,163 @@ ++From 70f119fb82af7f7417dc659faf02c91e1f853739 Mon Sep 17 00:00:00 2001 ++From: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Date: Mon, 16 May 2022 13:26:00 +0300 ++Subject: ath10k: htt_tx: do not interpret Eth frames as WiFi ++ ++The xmit path for the Ethernet encapsulated frames become more or less ++usable since d740d8fd2439 ("ath10k: unify tx mode and dispatch"). This ++change reorganize the xmit path in a manageable way to properly support ++various tx modes, but misses that the Ethernet encapsulated frame is a ++special case. We do not have an IEEE 802.11 header at the begining of ++them. But the HTT Tx handler still interprets first bytes of each frame ++as an IEEE 802.11 Frame Control field. ++ ++Than this code was copied by e62ee5c381c5 ("ath10k: Add support for ++htt_data_tx_desc_64 descriptor") and a2097d6444c3 ("ath10k: htt: High ++latency TX support") to another handlers. In fact the issue in the high ++latency (HL) handler was introduced by 83ac260151e7 ("ath10k: add mic ++bytes for pmf management packet"). ++ ++Ethernet encapsulated frame tx mode stay unused until 75d85fd9993c ++("ath10k: introduce basic tdls functionality") started using it for TDLS ++frames to avoid key selection issue in some firmwares. ++ ++Trying to interpret the begining of an Ethernet encapsulated frame as an ++IEEE 802.11 header was not hurt us noticeably since we need to meet two ++conditions: (1) xmit should be performed towards a TDLS peer, and (2) ++the TDLS peer should have a specific OUI part of its MAC address. Looks ++like that the rareness in TDLS communications of OUIs that can be ++interpreted as an 802.11 management frame saves users from facing this ++issue earlier. ++ ++Improve Ethernet tx mode support in the HTT Tx handler by avoiding ++interpreting its first bytes as an IEEE 802.11 header. While at it, make ++the ieee80211_hdr variable local to the code block that is guarded by ++!is_eth check. In this way, we clarify in which cases a frame can be ++interpreted as IEEE 802.11, and saves us from similar issues in the ++future. ++ ++Credits: this change as part of xmit encapsulation offloading support ++was originally made by QCA and then submitted for inclusion by John ++Crispin [1]. But the whole work was not accepted due to the lack of a ++part for 64-bits descriptors [2]. Zhijun You then pointed this out to me ++in a reply to my initial RFC patch series. And I made this slightly ++reworked version that covered all the HTT Tx handler variants. ++ ++1. https://lore.kernel.org/all/20191216092207.31032-1-john@phrozen.org/ ++2. https://patchwork.kernel.org/project/linux-wireless/patch/20191216092207.31032-1-john@phrozen.org/ ++ ++Reported-by: Zhijun You <hujy652@gmail.com> ++Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com> ++Signed-off-by: John Crispin <john@phrozen.org> ++Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> ++Link: https://lore.kernel.org/r/20220516032519.29831-3-ryazanov.s.a@gmail.com ++--- ++ drivers/net/wireless/ath/ath10k/htt_tx.c | 61 ++++++++++++++++++-------------- ++ 1 file changed, 35 insertions(+), 26 deletions(-) ++ ++--- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c ++@@ -1295,7 +1295,6 @@ static int ath10k_htt_tx_hl(struct ath10 ++ struct ath10k *ar = htt->ar; ++ int res, data_len; ++ struct htt_cmd_hdr *cmd_hdr; ++- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; ++ struct htt_data_tx_desc *tx_desc; ++ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); ++ struct sk_buff *tmp_skb; ++@@ -1306,11 +1305,15 @@ static int ath10k_htt_tx_hl(struct ath10 ++ u16 flags1 = 0; ++ u16 msdu_id = 0; ++ ++- if ((ieee80211_is_action(hdr->frame_control) || ++- ieee80211_is_deauth(hdr->frame_control) || ++- ieee80211_is_disassoc(hdr->frame_control)) && ++- ieee80211_has_protected(hdr->frame_control)) { ++- skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ if (!is_eth) { +++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; +++ +++ if ((ieee80211_is_action(hdr->frame_control) || +++ ieee80211_is_deauth(hdr->frame_control) || +++ ieee80211_is_disassoc(hdr->frame_control)) && +++ ieee80211_has_protected(hdr->frame_control)) { +++ skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ } ++ } ++ ++ data_len = msdu->len; ++@@ -1407,7 +1410,6 @@ static int ath10k_htt_tx_32(struct ath10 ++ { ++ struct ath10k *ar = htt->ar; ++ struct device *dev = ar->dev; ++- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); ++ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); ++ struct ath10k_hif_sg_item sg_items[2]; ++@@ -1439,15 +1441,19 @@ static int ath10k_htt_tx_32(struct ath10 ++ txbuf_paddr = htt->txbuf.paddr + ++ (sizeof(struct ath10k_htt_txbuf_32) * msdu_id); ++ ++- if ((ieee80211_is_action(hdr->frame_control) || ++- ieee80211_is_deauth(hdr->frame_control) || ++- ieee80211_is_disassoc(hdr->frame_control)) && ++- ieee80211_has_protected(hdr->frame_control)) { ++- skb_put(msdu, IEEE80211_CCMP_MIC_LEN); ++- } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && ++- txmode == ATH10K_HW_TXRX_RAW && ++- ieee80211_has_protected(hdr->frame_control)) { ++- skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ if (!is_eth) { +++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; +++ +++ if ((ieee80211_is_action(hdr->frame_control) || +++ ieee80211_is_deauth(hdr->frame_control) || +++ ieee80211_is_disassoc(hdr->frame_control)) && +++ ieee80211_has_protected(hdr->frame_control)) { +++ skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && +++ txmode == ATH10K_HW_TXRX_RAW && +++ ieee80211_has_protected(hdr->frame_control)) { +++ skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ } ++ } ++ ++ skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, ++@@ -1609,7 +1615,6 @@ static int ath10k_htt_tx_64(struct ath10 ++ { ++ struct ath10k *ar = htt->ar; ++ struct device *dev = ar->dev; ++- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); ++ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); ++ struct ath10k_hif_sg_item sg_items[2]; ++@@ -1641,15 +1646,19 @@ static int ath10k_htt_tx_64(struct ath10 ++ txbuf_paddr = htt->txbuf.paddr + ++ (sizeof(struct ath10k_htt_txbuf_64) * msdu_id); ++ ++- if ((ieee80211_is_action(hdr->frame_control) || ++- ieee80211_is_deauth(hdr->frame_control) || ++- ieee80211_is_disassoc(hdr->frame_control)) && ++- ieee80211_has_protected(hdr->frame_control)) { ++- skb_put(msdu, IEEE80211_CCMP_MIC_LEN); ++- } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && ++- txmode == ATH10K_HW_TXRX_RAW && ++- ieee80211_has_protected(hdr->frame_control)) { ++- skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ if (!is_eth) { +++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; +++ +++ if ((ieee80211_is_action(hdr->frame_control) || +++ ieee80211_is_deauth(hdr->frame_control) || +++ ieee80211_is_disassoc(hdr->frame_control)) && +++ ieee80211_has_protected(hdr->frame_control)) { +++ skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && +++ txmode == ATH10K_HW_TXRX_RAW && +++ ieee80211_has_protected(hdr->frame_control)) { +++ skb_put(msdu, IEEE80211_CCMP_MIC_LEN); +++ } ++ } ++ ++ skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, +diff --git a/package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch b/package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch +new file mode 100644 +index 0000000000..abca7aac9e +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/081-04-ath10k-add-encapsulation-offloading-support.patch +@@ -0,0 +1,194 @@ ++From af6d8265c47e46881b80c6b073f53c8c4af52d28 Mon Sep 17 00:00:00 2001 ++From: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Date: Mon, 16 May 2022 13:26:00 +0300 ++Subject: ath10k: add encapsulation offloading support ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++Frame encapsulation from Ethernet into the IEEE 802.11 frame format ++takes a considerable host CPU time on the xmit path. The firmware is ++able to do this operation for us, so enable encapsulation offloading for ++AP and Sta interface types to improve overall system performance. ++ ++The driver is almost ready for encapsulation offloading support. There ++are only a few places where the driver assumes the frame format is IEEE ++802.11 that need to be fixed. ++ ++Encapsulation offloading is currently disabled by default and the driver ++utilizes mac80211 encapsulation support. To activate offloading, the ++frame_mode=2 parameter should be passed during module loading. ++ ++On a QCA9563+QCA9888-based access point in bridged mode, encapsulation ++offloading increases TCP 16-streams DL throughput from 365 to 396 mbps ++(+8%) and UDP DL throughput from 436 to 483 mbps (+11%). ++ ++Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131 ++Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1 ++Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com> ++Tested-by: OldÅ™ich JedliÄka <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880) ++Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1) ++Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode ++Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159) ++Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> ++Link: https://lore.kernel.org/r/20220516032519.29831-5-ryazanov.s.a@gmail.com ++--- ++ drivers/net/wireless/ath/ath10k/core.c | 2 +- ++ drivers/net/wireless/ath/ath10k/mac.c | 67 +++++++++++++++++++++++++++------- ++ 2 files changed, 55 insertions(+), 14 deletions(-) ++ ++--- a/drivers/net/wireless/ath/ath10k/core.c +++++ b/drivers/net/wireless/ath/ath10k/core.c ++@@ -54,7 +54,7 @@ MODULE_PARM_DESC(uart_print, "Uart targe ++ MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); ++ MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software"); ++ MODULE_PARM_DESC(frame_mode, ++- "Datapath frame mode (0: raw, 1: native wifi (default))"); +++ "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); ++ MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); ++ MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); ++ ++--- a/drivers/net/wireless/ath/ath10k/mac.c +++++ b/drivers/net/wireless/ath/ath10k/mac.c ++@@ -3710,6 +3710,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k ++ const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); ++ __le16 fc = hdr->frame_control; ++ +++ if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) +++ return ATH10K_HW_TXRX_ETHERNET; +++ ++ if (!vif || vif->type == NL80211_IFTYPE_MONITOR) ++ return ATH10K_HW_TXRX_RAW; ++ ++@@ -3870,6 +3873,12 @@ static void ath10k_mac_tx_h_fill_cb(stru ++ bool noack = false; ++ ++ cb->flags = 0; +++ +++ if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { +++ cb->flags |= ATH10K_SKB_F_QOS; /* Assume data frames are QoS */ +++ goto finish_cb_fill; +++ } +++ ++ if (!ath10k_tx_h_use_hwcrypto(vif, skb)) ++ cb->flags |= ATH10K_SKB_F_NO_HWCRYPT; ++ ++@@ -3908,6 +3917,7 @@ static void ath10k_mac_tx_h_fill_cb(stru ++ cb->flags |= ATH10K_SKB_F_RAW_TX; ++ } ++ +++finish_cb_fill: ++ cb->vif = vif; ++ cb->txq = txq; ++ cb->airtime_est = airtime; ++@@ -4031,7 +4041,11 @@ static int ath10k_mac_tx(struct ath10k * ++ ath10k_tx_h_seq_no(vif, skb); ++ break; ++ case ATH10K_HW_TXRX_ETHERNET: ++- ath10k_tx_h_8023(skb); +++ /* Convert 802.11->802.3 header only if the frame was erlier +++ * encapsulated to 802.11 by mac80211. Otherwise pass it as is. +++ */ +++ if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) +++ ath10k_tx_h_8023(skb); ++ break; ++ case ATH10K_HW_TXRX_RAW: ++ if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) && ++@@ -4643,12 +4657,10 @@ static void ath10k_mac_op_tx(struct ieee ++ struct ieee80211_vif *vif = info->control.vif; ++ struct ieee80211_sta *sta = control->sta; ++ struct ieee80211_txq *txq = NULL; ++- struct ieee80211_hdr *hdr = (void *)skb->data; ++ enum ath10k_hw_txrx_mode txmode; ++ enum ath10k_mac_tx_path txpath; ++ bool is_htt; ++ bool is_mgmt; ++- bool is_presp; ++ int ret; ++ u16 airtime; ++ ++@@ -4662,8 +4674,14 @@ static void ath10k_mac_op_tx(struct ieee ++ is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT); ++ ++ if (is_htt) { +++ bool is_presp = false; +++ ++ spin_lock_bh(&ar->htt.tx_lock); ++- is_presp = ieee80211_is_probe_resp(hdr->frame_control); +++ if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) { +++ struct ieee80211_hdr *hdr = (void *)skb->data; +++ +++ is_presp = ieee80211_is_probe_resp(hdr->frame_control); +++ } ++ ++ ret = ath10k_htt_tx_inc_pending(htt); ++ if (ret) { ++@@ -5463,6 +5481,30 @@ static int ath10k_mac_set_txbf_conf(stru ++ ar->wmi.vdev_param->txbf, value); ++ } ++ +++static void ath10k_update_vif_offload(struct ieee80211_hw *hw, +++ struct ieee80211_vif *vif) +++{ +++ struct ath10k_vif *arvif = (void *)vif->drv_priv; +++ struct ath10k *ar = hw->priv; +++ u32 vdev_param; +++ int ret; +++ +++ if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET || +++ ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED || +++ (vif->type != NL80211_IFTYPE_STATION && +++ vif->type != NL80211_IFTYPE_AP)) +++ vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; +++ +++ vdev_param = ar->wmi.vdev_param->tx_encap_type; +++ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, +++ ATH10K_HW_TXRX_NATIVE_WIFI); +++ /* 10.X firmware does not support this VDEV parameter. Do not warn */ +++ if (ret && ret != -EOPNOTSUPP) { +++ ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", +++ arvif->vdev_id, ret); +++ } +++} +++ ++ /* ++ * TODO: ++ * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE, ++@@ -5672,15 +5714,7 @@ static int ath10k_add_interface(struct i ++ ++ arvif->def_wep_key_idx = -1; ++ ++- vdev_param = ar->wmi.vdev_param->tx_encap_type; ++- ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ++- ATH10K_HW_TXRX_NATIVE_WIFI); ++- /* 10.X firmware does not support this VDEV parameter. Do not warn */ ++- if (ret && ret != -EOPNOTSUPP) { ++- ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", ++- arvif->vdev_id, ret); ++- goto err_vdev_delete; ++- } +++ ath10k_update_vif_offload(hw, vif); ++ ++ /* Configuring number of spatial stream for monitor interface is causing ++ * target assert in qca9888 and qca6174. ++@@ -9368,6 +9402,7 @@ static const struct ieee80211_ops ath10k ++ .stop = ath10k_stop, ++ .config = ath10k_config, ++ .add_interface = ath10k_add_interface, +++ .update_vif_offload = ath10k_update_vif_offload, ++ .remove_interface = ath10k_remove_interface, ++ .configure_filter = ath10k_configure_filter, ++ .bss_info_changed = ath10k_bss_info_changed, ++@@ -10037,6 +10072,12 @@ int ath10k_mac_register(struct ath10k *a ++ if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) ++ ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA); ++ +++ if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) { +++ if (ar->wmi.vdev_param->tx_encap_type != +++ WMI_VDEV_PARAM_UNSUPPORTED) +++ ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); +++ } +++ ++ ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; ++ ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; ++ ar->hw->wiphy->max_remain_on_channel_duration = 5000; +diff --git a/package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch b/package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch +new file mode 100644 +index 0000000000..7ef418e506 +--- /dev/null ++++ b/package/kernel/mac80211/patches/ath10k/100-ath10k-support-bus-and-device-specific-API-1-BDF-sel.patch +@@ -0,0 +1,65 @@ ++From f2a7064a78b22f2b68b9fcbc8a6f4c5e61c5ba64 Mon Sep 17 00:00:00 2001 ++From: Robert Marko <robimarko@gmail.com> ++Date: Sun, 10 Oct 2021 00:17:11 +0200 ++Subject: [PATCH] ath10k: support bus and device specific API 1 BDF selection ++ ++Some ath10k IPQ40xx devices like the MikroTik hAP ac2 and ac3 require the ++BDF-s to be extracted from the device storage instead of shipping packaged ++API 2 BDF-s. ++ ++This is required as MikroTik has started shipping boards that require BDF-s ++to be updated, as otherwise their WLAN performance really suffers. ++This is however impossible as the devices that require this are release ++under the same revision and its not possible to differentiate them from ++devices using the older BDF-s. ++ ++In OpenWrt we are extracting the calibration data during runtime and we are ++able to extract the BDF-s in the same manner, however we cannot package the ++BDF-s to API 2 format on the fly and can only use API 1 to provide BDF-s on ++the fly. ++This is an issue as the ath10k driver explicitly looks only for the ++board.bin file and not for something like board-bus-device.bin like it does ++for pre-cal data. ++Due to this we have no way of providing correct BDF-s on the fly, so lets ++extend the ath10k driver to first look for BDF-s in the ++board-bus-device.bin format, for example: board-ahb-a800000.wifi.bin ++If that fails, look for the default board file name as defined previously. ++ ++Signed-off-by: Robert Marko <robimarko@gmail.com> ++Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> ++Link: https://lore.kernel.org/r/20211009221711.2315352-1-robimarko@gmail.com ++--- ++ drivers/net/wireless/ath/ath10k/core.c | 13 ++++++++++++- ++ 1 file changed, 12 insertions(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ath/ath10k/core.c +++++ b/drivers/net/wireless/ath/ath10k/core.c ++@@ -1202,6 +1202,7 @@ success: ++ static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type) ++ { ++ const struct firmware *fw; +++ char boardname[100]; ++ ++ if (bd_ie_type == ATH10K_BD_IE_BOARD) { ++ if (!ar->hw_params.fw.board) { ++@@ -1209,9 +1210,19 @@ static int ath10k_core_fetch_board_data_ ++ return -EINVAL; ++ } ++ +++ scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin", +++ ath10k_bus_str(ar->hif.bus), dev_name(ar->dev)); +++ ++ ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar, ++ ar->hw_params.fw.dir, ++- ar->hw_params.fw.board); +++ boardname); +++ if (IS_ERR(ar->normal_mode_fw.board)) { +++ fw = ath10k_fetch_fw_file(ar, +++ ar->hw_params.fw.dir, +++ ar->hw_params.fw.board); +++ ar->normal_mode_fw.board = fw; +++ } +++ ++ if (IS_ERR(ar->normal_mode_fw.board)) ++ return PTR_ERR(ar->normal_mode_fw.board); ++ diff --git a/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch new file mode 100644 -index 0000000000..bebd5fe6c2 +index 0000000000..c7a00b7e4b --- /dev/null +++ b/package/kernel/mac80211/patches/ath10k/120-ath10k-fetch-calibration-data-via-nvmem-subsystem.patch @@ -0,0 +1,162 @@ @@ -789,7 +1730,7 @@ index 0000000000..bebd5fe6c2 + #include <asm/byteorder.h> + + #include "core.h" -+@@ -952,7 +953,8 @@ static int ath10k_core_get_board_id_from ++@@ -955,7 +956,8 @@ static int ath10k_core_get_board_id_from + } + + if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT || @@ -799,7 +1740,7 @@ index 0000000000..bebd5fe6c2 + bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID; + else + bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID; -+@@ -1743,7 +1745,8 @@ static int ath10k_download_and_run_otp(s ++@@ -1757,7 +1759,8 @@ static int ath10k_download_and_run_otp(s + + /* As of now pre-cal is valid for 10_4 variants */ + if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT || @@ -809,7 +1750,7 @@ index 0000000000..bebd5fe6c2 + bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL; + + ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result); -+@@ -1870,6 +1873,39 @@ out_free: ++@@ -1884,6 +1887,39 @@ out_free: + return ret; + } + @@ -849,7 +1790,7 @@ index 0000000000..bebd5fe6c2 + int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name, + struct ath10k_fw_file *fw_file) + { -+@@ -2104,6 +2140,18 @@ static int ath10k_core_pre_cal_download( ++@@ -2118,6 +2154,18 @@ static int ath10k_core_pre_cal_download( + { + int ret; + @@ -868,7 +1809,7 @@ index 0000000000..bebd5fe6c2 + ret = ath10k_download_cal_file(ar, ar->pre_cal_file); + if (ret == 0) { + ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE; -+@@ -2170,6 +2218,18 @@ static int ath10k_download_cal_data(stru ++@@ -2184,6 +2232,18 @@ static int ath10k_download_cal_data(stru + "pre cal download procedure failed, try cal file: %d\n", + ret); + @@ -919,7 +1860,7 @@ diff --git a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchro similarity index 94% rename from package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch rename to package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch -index 2b8fe7816f..b6ae2c7c83 100644 +index 2b8fe7816f..e47fb012fa 100644 --- a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch @@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com> @@ -927,7 +1868,7 @@ index 2b8fe7816f..b6ae2c7c83 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -3206,6 +3206,16 @@ int ath10k_core_register(struct ath10k * -+@@ -3429,6 +3429,16 @@ int ath10k_core_register(struct ath10k * ++@@ -3443,6 +3443,16 @@ int ath10k_core_register(struct ath10k * queue_work(ar->workqueue, &ar->register_work); @@ -935,14 +1876,14 @@ diff --git a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger. similarity index 89% rename from package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch rename to package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch -index 41022b873a..b60db19464 100644 +index 41022b873a..9dfde4385e 100644 --- a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/ath10k/930-ath10k_add_tpt_led_trigger.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -9732,6 +9732,21 @@ static int ath10k_mac_init_rd(struct ath -+@@ -9843,6 +9843,21 @@ static int ath10k_mac_init_rd(struct ath ++@@ -9894,6 +9894,21 @@ static int ath10k_mac_init_rd(struct ath return 0; } @@ -951,7 +1892,7 @@ index 41022b873a..b60db19464 100644 { static const u32 cipher_suites[] = { -@@ -10081,6 +10096,12 @@ int ath10k_mac_register(struct ath10k *a -+@@ -10195,6 +10210,12 @@ int ath10k_mac_register(struct ath10k *a ++@@ -10252,6 +10267,12 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; @@ -959,7 +1900,7 @@ diff --git a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-con similarity index 96% rename from package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch rename to package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch -index d8c8a8abc0..6db2430749 100644 +index d8c8a8abc0..47b52416ab 100644 --- a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +++ b/package/kernel/mac80211/patches/ath10k/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -85,7 +85,7 @@ v13: @@ -976,7 +1917,7 @@ index d8c8a8abc0..6db2430749 100644 --- a/local-symbols +++ b/local-symbols -@@ -145,6 +145,7 @@ ATH10K_DEBUG= -+@@ -143,6 +143,7 @@ ATH10K_DEBUG= ++@@ -166,6 +166,7 @@ ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= ATH10K_THERMAL= @@ -994,7 +1935,7 @@ index d8c8a8abc0..6db2430749 100644 unsigned int ath10k_debug_mask; EXPORT_SYMBOL(ath10k_debug_mask); -@@ -61,6 +62,7 @@ static const struct ath10k_hw_params ath -+@@ -62,6 +63,7 @@ static const struct ath10k_hw_params ath ++@@ -65,6 +66,7 @@ static const struct ath10k_hw_params ath .dev_id = QCA988X_2_0_DEVICE_ID, .bus = ATH10K_BUS_PCI, .name = "qca988x hw2.0", @@ -1003,7 +1944,7 @@ index d8c8a8abc0..6db2430749 100644 .uart_pin = 7, .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, -@@ -132,6 +134,7 @@ static const struct ath10k_hw_params ath -+@@ -135,6 +137,7 @@ static const struct ath10k_hw_params ath ++@@ -138,6 +140,7 @@ static const struct ath10k_hw_params ath .dev_id = QCA9887_1_0_DEVICE_ID, .bus = ATH10K_BUS_PCI, .name = "qca9887 hw1.0", @@ -1012,7 +1953,7 @@ index d8c8a8abc0..6db2430749 100644 .uart_pin = 7, .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, -@@ -343,6 +346,7 @@ static const struct ath10k_hw_params ath -+@@ -352,6 +355,7 @@ static const struct ath10k_hw_params ath ++@@ -355,6 +358,7 @@ static const struct ath10k_hw_params ath .dev_id = QCA99X0_2_0_DEVICE_ID, .bus = ATH10K_BUS_PCI, .name = "qca99x0 hw2.0", @@ -1021,7 +1962,7 @@ index d8c8a8abc0..6db2430749 100644 .uart_pin = 7, .otp_exe_param = 0x00000700, -@@ -384,6 +388,7 @@ static const struct ath10k_hw_params ath -+@@ -394,6 +398,7 @@ static const struct ath10k_hw_params ath ++@@ -397,6 +401,7 @@ static const struct ath10k_hw_params ath .dev_id = QCA9984_1_0_DEVICE_ID, .bus = ATH10K_BUS_PCI, .name = "qca9984/qca9994 hw1.0", @@ -1030,7 +1971,7 @@ index d8c8a8abc0..6db2430749 100644 .uart_pin = 7, .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, -@@ -432,6 +437,7 @@ static const struct ath10k_hw_params ath -+@@ -443,6 +448,7 @@ static const struct ath10k_hw_params ath ++@@ -446,6 +451,7 @@ static const struct ath10k_hw_params ath .dev_id = QCA9888_2_0_DEVICE_ID, .bus = ATH10K_BUS_PCI, .name = "qca9888 hw2.0", @@ -1039,7 +1980,7 @@ index d8c8a8abc0..6db2430749 100644 .uart_pin = 7, .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, -@@ -2921,6 +2927,10 @@ int ath10k_core_start(struct ath10k *ar, -+@@ -3144,6 +3150,10 @@ int ath10k_core_start(struct ath10k *ar, ++@@ -3158,6 +3164,10 @@ int ath10k_core_start(struct ath10k *ar, goto err_hif_stop; } @@ -1048,7 +1989,7 @@ index d8c8a8abc0..6db2430749 100644 err_hif_stop: -@@ -3179,9 +3189,18 @@ static void ath10k_core_register_work(st -+@@ -3402,9 +3412,18 @@ static void ath10k_core_register_work(st ++@@ -3416,9 +3426,18 @@ static void ath10k_core_register_work(st goto err_spectral_destroy; } @@ -1057,7 +1998,7 @@ index d8c8a8abc0..6db2430749 100644 ath10k_spectral_destroy(ar); err_debug_destroy: -@@ -3227,6 +3246,8 @@ void ath10k_core_unregister(struct ath10 -+@@ -3450,6 +3469,8 @@ void ath10k_core_unregister(struct ath10 ++@@ -3464,6 +3483,8 @@ void ath10k_core_unregister(struct ath10 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; @@ -1074,7 +2015,7 @@ diff --git a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-d similarity index 92% rename from package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch rename to package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch -index 5781f9c7ad..da31ad578a 100644 +index 5781f9c7ad..842853ddf4 100644 --- a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch +++ b/package/kernel/mac80211/patches/ath10k/975-ath10k-use-tpt-trigger-by-default.patch @@ -16,9 +16,9 @@ Signed-off-by: Mathias Kresin <dev@kresin.me> @@ -1095,7 +2036,7 @@ index 5781f9c7ad..da31ad578a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -10098,7 +10098,7 @@ int ath10k_mac_register(struct ath10k *a -+@@ -10212,7 +10212,7 @@ int ath10k_mac_register(struct ath10k *a ++@@ -10269,7 +10269,7 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; #ifdef CPTCFG_MAC80211_LEDS @@ -1144,7 +2085,7 @@ index 1f19765891..a45addf119 100644 ch->max_reg_power = channel->max_reg_power * 2; diff --git a/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch new file mode 100644 -index 0000000000..4077b2f393 +index 0000000000..80da07de8a --- /dev/null +++ b/package/kernel/mac80211/patches/ath10k/984-ath10k-Try-to-get-mac-address-from-dts.patch @@ -0,0 +1,37 @@ @@ -1176,7 +2117,7 @@ index 0000000000..4077b2f393 + #include <linux/property.h> + #include <linux/dmi.h> + #include <linux/ctype.h> -+@@ -3320,6 +3321,8 @@ static int ath10k_core_probe_fw(struct a ++@@ -3334,6 +3335,8 @@ static int ath10k_core_probe_fw(struct a + + device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr)); + @@ -1749,7 +2690,7 @@ diff --git a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.pat similarity index 99% rename from package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch rename to package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch -index e9cf00769d..291bc6d1e1 100644 +index e9cf00769d..6b5c0dc514 100644 --- a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch +++ b/package/kernel/mac80211/patches/ath9k/551-ath9k_ubnt_uap_plus_hsr.patch @@ -371,7 +371,7 @@ @@ -1757,7 +2698,7 @@ index e9cf00769d..291bc6d1e1 100644 --- a/local-symbols +++ b/local-symbols -@@ -112,6 +112,7 @@ ATH9K_WOW= -+@@ -110,6 +110,7 @@ ATH9K_WOW= ++@@ -133,6 +133,7 @@ ATH9K_WOW= ATH9K_RFKILL= ATH9K_CHANNEL_CONTEXT= ATH9K_PCOEM= @@ -1859,10 +2800,6 @@ index 8e0041e3ef..80e0dc4c5e 100644 if (ret) goto err_hw; -diff --git a/package/kernel/mac80211/patches/ath/580-ath9k_ar9561_fix_bias_level.patch b/package/kernel/mac80211/patches/ath9k/580-ath9k_ar9561_fix_bias_level.patch -similarity index 100% -rename from package/kernel/mac80211/patches/ath/580-ath9k_ar9561_fix_bias_level.patch -rename to package/kernel/mac80211/patches/ath9k/580-ath9k_ar9561_fix_bias_level.patch diff --git a/package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch b/package/kernel/mac80211/patches/ath9k/600-v5.16-ath9k-fetch-calibration-data-via-nvmem-subsystem.patch new file mode 100644 index 0000000000..a250d2318e @@ -2210,6 +3147,115 @@ index 0000000000..62c561d619 + if (err) + dev_err(&pdev->dev, "failed to request caldata (%d).\n", err); + +diff --git a/package/kernel/mac80211/patches/brcm/001-brcmfmac-allow-setting-wlan-MAC-address-using-device.patch b/package/kernel/mac80211/patches/brcm/001-brcmfmac-allow-setting-wlan-MAC-address-using-device.patch +new file mode 100644 +index 0000000000..03d9f8ecd8 +--- /dev/null ++++ b/package/kernel/mac80211/patches/brcm/001-brcmfmac-allow-setting-wlan-MAC-address-using-device.patch +@@ -0,0 +1,103 @@ ++From 716c220b4d990a4fe7800d0685ca69dee99e4e8f Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Pavel=20L=C3=B6bl?= <pavel@loebl.cz> ++Date: Fri, 6 May 2022 06:42:46 +0200 ++Subject: [PATCH] brcmfmac: allow setting wlan MAC address using device tree ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++This allows firmware to provide MAC address using device tree. Like in ++case there is no MAC burned in wlan NVRAM. ++ ++Signed-off-by: Pavel Löbl <pavel@loebl.cz> ++Signed-off-by: Kalle Valo <kvalo@kernel.org> ++Link: https://lore.kernel.org/r/20220506044246.67146-1-pavel@loebl.cz ++--- ++ .../broadcom/brcm80211/brcmfmac/common.c | 23 ++++++++++++++----- ++ .../broadcom/brcm80211/brcmfmac/common.h | 1 + ++ .../broadcom/brcm80211/brcmfmac/core.c | 4 +++- ++ .../wireless/broadcom/brcm80211/brcmfmac/of.c | 3 +++ ++ 4 files changed, 24 insertions(+), 7 deletions(-) ++ ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++@@ -202,13 +202,24 @@ int brcmf_c_preinit_dcmds(struct brcmf_i ++ char *ptr; ++ s32 err; ++ ++- /* retreive mac address */ ++- err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, ++- sizeof(ifp->mac_addr)); ++- if (err < 0) { ++- bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err); ++- goto done; +++ if (is_valid_ether_addr(ifp->mac_addr)) { +++ /* set mac address */ +++ err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, +++ ETH_ALEN); +++ if (err < 0) { +++ bphy_err(ifp->drvr, "Setting cur_etheraddr failed, %d\n", err); +++ goto done; +++ } +++ } else { +++ /* retrieve mac address */ +++ err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, +++ sizeof(ifp->mac_addr)); +++ if (err < 0) { +++ bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err); +++ goto done; +++ } ++ } +++ ++ memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); ++ memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); ++ ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++@@ -50,6 +50,7 @@ struct brcmf_mp_device { ++ bool ignore_probe_fail; ++ struct brcmfmac_pd_cc *country_codes; ++ const char *board_type; +++ unsigned char mac[ETH_ALEN]; ++ union { ++ struct brcmfmac_sdio_pd sdio; ++ } bus; ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++@@ -7,6 +7,7 @@ ++ #include <linux/etherdevice.h> ++ #include <linux/module.h> ++ #include <linux/inetdevice.h> +++#include <linux/property.h> ++ #include <net/cfg80211.h> ++ #include <net/rtnetlink.h> ++ #include <net/addrconf.h> ++@@ -1226,7 +1227,8 @@ static int brcmf_bus_started(struct brcm ++ brcmf_dbg(TRACE, "\n"); ++ ++ /* add primary networking interface */ ++- ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL); +++ ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", +++ is_valid_ether_addr(drvr->settings->mac) ? drvr->settings->mac : NULL); ++ if (IS_ERR(ifp)) ++ return PTR_ERR(ifp); ++ ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++@@ -5,6 +5,7 @@ ++ #include <linux/init.h> ++ #include <linux/of.h> ++ #include <linux/of_irq.h> +++#include <linux/of_net.h> ++ ++ #include <defs.h> ++ #include "debug.h" ++@@ -97,6 +98,8 @@ void brcmf_of_probe(struct device *dev, ++ if (err) ++ brcmf_err("failed to get OF country code map (err=%d)\n", err); ++ +++ of_get_mac_address(np, settings->mac); +++ ++ if (bus_type != BRCMF_BUSTYPE_SDIO) ++ return; ++ diff --git a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch index 52ae7a8eba..5dc04ecc88 100644 --- a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch @@ -2320,7 +3366,7 @@ index 774656f1fd..88465f256b 100644 * FW later while initializing the dongle */ diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch -index 9658bda1c1..835c870a65 100644 +index 9658bda1c1..1ddc78f7ca 100644 --- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +++ b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch @@ -12,9 +12,9 @@ Signed-off-by: RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl> @@ -2330,7 +3376,7 @@ index 9658bda1c1..835c870a65 100644 -@@ -12,6 +12,36 @@ - #include "common.h" - #include "of.h" -+@@ -58,6 +58,36 @@ static int brcmf_of_get_country_codes(st ++@@ -59,6 +59,36 @@ static int brcmf_of_get_country_codes(st + return 0; + } @@ -2341,7 +3387,7 @@ index 9658bda1c1..835c870a65 100644 struct brcmf_mp_device *settings) { -@@ -43,6 +73,8 @@ void brcmf_of_probe(struct device *dev, -+@@ -90,6 +120,8 @@ void brcmf_of_probe(struct device *dev, ++@@ -91,6 +121,8 @@ void brcmf_of_probe(struct device *dev, of_node_put(root); } @@ -2352,8 +3398,210 @@ index 9658bda1c1..835c870a65 100644 + if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) return; + +diff --git a/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch +new file mode 100644 +index 0000000000..8adb8c42a1 +--- /dev/null ++++ b/package/kernel/mac80211/patches/brcm/865-brcmfmac-Read-alternative-firmware-names-from-DT.patch +@@ -0,0 +1,196 @@ ++From 4e32024cbb14230af3048e249e84f8c2b25ce45a Mon Sep 17 00:00:00 2001 ++From: Phil Elwell <phil@raspberrypi.com> ++Date: Thu, 28 Oct 2021 15:03:16 +0100 ++Subject: [PATCH] brcmfmac: Read alternative firmware names from DT ++ ++Add the ability to load the names of alternative firmwares from the ++Device Tree node. This permits separate firmwares for 43436s and 43438 ++and allows downstream firmwares to coexist with upstream. ++ ++Signed-off-by: Phil Elwell <phil@raspberrypi.com> ++--- ++ .../wireless/broadcom/brcm80211/brcmfmac/of.c | 36 ++++++++++++++ ++ .../wireless/broadcom/brcm80211/brcmfmac/of.h | 7 +++ ++ .../broadcom/brcm80211/brcmfmac/sdio.c | 47 +++++++++++++++++-- ++ 3 files changed, 87 insertions(+), 3 deletions(-) ++ ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++@@ -11,6 +11,7 @@ ++ #include "debug.h" ++ #include "core.h" ++ #include "common.h" +++#include "firmware.h" ++ #include "of.h" ++ ++ static int brcmf_of_get_country_codes(struct device *dev, ++@@ -153,3 +154,38 @@ void brcmf_of_probe(struct device *dev, ++ sdio->oob_irq_nr = irq; ++ sdio->oob_irq_flags = irqf; ++ } +++ +++struct brcmf_firmware_mapping * +++brcmf_of_fwnames(struct device *dev, u32 *fwname_count) +++{ +++ struct device_node *np = dev->of_node; +++ struct brcmf_firmware_mapping *fwnames; +++ struct device_node *map_np, *fw_np; +++ int of_count; +++ int count = 0; +++ +++ map_np = of_get_child_by_name(np, "firmwares"); +++ of_count = of_get_child_count(map_np); +++ if (!of_count) +++ return NULL; +++ +++ fwnames = devm_kcalloc(dev, of_count, +++ sizeof(struct brcmf_firmware_mapping), +++ GFP_KERNEL); +++ +++ for_each_child_of_node(map_np, fw_np) +++ { +++ struct brcmf_firmware_mapping *cur = &fwnames[count]; +++ +++ if (of_property_read_u32(fw_np, "chipid", &cur->chipid) || +++ of_property_read_u32(fw_np, "revmask", &cur->revmask)) +++ continue; +++ cur->fw_base = of_get_property(fw_np, "fw_base", NULL); +++ if (cur->fw_base) +++ count++; +++ } +++ +++ *fwname_count = count; +++ +++ return count ? fwnames : NULL; +++} ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h ++@@ -5,9 +5,16 @@ ++ #ifdef CONFIG_OF ++ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, ++ struct brcmf_mp_device *settings); +++struct brcmf_firmware_mapping * +++brcmf_of_fwnames(struct device *dev, u32 *map_count); ++ #else ++ static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, ++ struct brcmf_mp_device *settings) ++ { ++ } +++static struct brcmf_firmware_mapping * +++brcmf_of_fwnames(struct device *dev, u32 *map_count) +++{ +++ return NULL; +++} ++ #endif /* CONFIG_OF */ ++--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++@@ -35,6 +35,7 @@ ++ #include "core.h" ++ #include "common.h" ++ #include "bcdc.h" +++#include "of.h" ++ ++ #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) ++ #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) ++@@ -633,7 +634,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "b ++ /* per-board firmware binaries */ ++ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin"); ++ ++-static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { +++static const struct brcmf_firmware_mapping sdio_fwnames[] = { ++ BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), ++ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), ++ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), ++@@ -659,6 +660,9 @@ static const struct brcmf_firmware_mappi ++ BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752) ++ }; ++ +++static const struct brcmf_firmware_mapping *brcmf_sdio_fwnames = sdio_fwnames; +++static u32 brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames); +++ ++ #define TXCTL_CREDITS 2 ++ ++ static void pkt_align(struct sk_buff *p, int len, int align) ++@@ -4140,7 +4144,7 @@ int brcmf_sdio_get_fwname(struct device ++ ++ fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, ++ brcmf_sdio_fwnames, ++- ARRAY_SIZE(brcmf_sdio_fwnames), +++ brcmf_sdio_fwnames_count, ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return -ENOMEM; ++@@ -4196,6 +4200,9 @@ static const struct brcmf_bus_ops brcmf_ ++ #define BRCMF_SDIO_FW_CODE 0 ++ #define BRCMF_SDIO_FW_NVRAM 1 ++ +++static struct brcmf_fw_request * +++brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus); +++ ++ static void brcmf_sdio_firmware_callback(struct device *dev, int err, ++ struct brcmf_fw_request *fwreq) ++ { ++@@ -4211,6 +4218,22 @@ static void brcmf_sdio_firmware_callback ++ ++ brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); ++ +++ if (err && brcmf_sdio_fwnames != sdio_fwnames) { +++ /* Try again with the standard firmware names */ +++ brcmf_sdio_fwnames = sdio_fwnames; +++ brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames); +++ kfree(fwreq); +++ fwreq = brcmf_sdio_prepare_fw_request(bus); +++ if (!fwreq) { +++ err = -ENOMEM; +++ goto fail; +++ } +++ err = brcmf_fw_get_firmwares(dev, fwreq, +++ brcmf_sdio_firmware_callback); +++ if (!err) +++ return; +++ } +++ ++ if (err) ++ goto fail; ++ ++@@ -4419,7 +4442,7 @@ brcmf_sdio_prepare_fw_request(struct brc ++ ++ fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, ++ brcmf_sdio_fwnames, ++- ARRAY_SIZE(brcmf_sdio_fwnames), +++ brcmf_sdio_fwnames_count, ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return NULL; ++@@ -4437,6 +4460,9 @@ struct brcmf_sdio *brcmf_sdio_probe(stru ++ struct brcmf_sdio *bus; ++ struct workqueue_struct *wq; ++ struct brcmf_fw_request *fwreq; +++ struct brcmf_firmware_mapping *of_fwnames, *fwnames = NULL; +++ const int fwname_size = sizeof(struct brcmf_firmware_mapping); +++ u32 of_fw_count; ++ ++ brcmf_dbg(TRACE, "Enter\n"); ++ ++@@ -4519,6 +4545,21 @@ struct brcmf_sdio *brcmf_sdio_probe(stru ++ ++ brcmf_dbg(INFO, "completed!!\n"); ++ +++ of_fwnames = brcmf_of_fwnames(sdiodev->dev, &of_fw_count); +++ if (of_fwnames) +++ fwnames = devm_kcalloc(sdiodev->dev, +++ of_fw_count + brcmf_sdio_fwnames_count, +++ fwname_size, GFP_KERNEL); +++ +++ if (fwnames) { +++ /* The array is scanned in order, so overrides come first */ +++ memcpy(fwnames, of_fwnames, of_fw_count * fwname_size); +++ memcpy(fwnames + of_fw_count, sdio_fwnames, +++ brcmf_sdio_fwnames_count * fwname_size); +++ brcmf_sdio_fwnames = fwnames; +++ brcmf_sdio_fwnames_count += of_fw_count; +++ } +++ ++ fwreq = brcmf_sdio_prepare_fw_request(bus); ++ if (!fwreq) { ++ ret = -ENOMEM; diff --git a/package/kernel/mac80211/patches/brcm/998-survey.patch b/package/kernel/mac80211/patches/brcm/998-survey.patch -index 25a12c783e..a5efc08015 100644 +index 25a12c783e..d194e25177 100644 --- a/package/kernel/mac80211/patches/brcm/998-survey.patch +++ b/package/kernel/mac80211/patches/brcm/998-survey.patch @@ -1,6 +1,6 @@ @@ -2396,7 +3644,7 @@ index 25a12c783e..a5efc08015 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1356,6 +1356,8 @@ int brcmf_attach(struct device *dev) -+@@ -1361,6 +1361,8 @@ int brcmf_attach(struct device *dev) ++@@ -1363,6 +1363,8 @@ int brcmf_attach(struct device *dev) /* Link to bus module */ drvr->hdrlen = 0; @@ -2405,7 +3653,7 @@ index 25a12c783e..a5efc08015 100644 /* Attach and link in the protocol */ ret = brcmf_proto_attach(drvr); -@@ -1438,6 +1440,12 @@ void brcmf_detach(struct device *dev) -+@@ -1443,6 +1445,12 @@ void brcmf_detach(struct device *dev) ++@@ -1445,6 +1447,12 @@ void brcmf_detach(struct device *dev) if (drvr == NULL) return; @@ -2477,7 +3725,7 @@ index d5253063ce..0000000000 - #include_next <linux/rfkill.h> - #else diff --git a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch -index ff2ce2071f..19a60d7956 100644 +index ff2ce2071f..089ff2117b 100644 --- a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch +++ b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch @@ -1,9 +1,9 @@ @@ -2485,7 +3733,7 @@ index ff2ce2071f..19a60d7956 100644 +++ b/local-symbols -@@ -437,43 +437,6 @@ USB_SIERRA_NET= - USB_VL600= -+@@ -428,43 +428,6 @@ USB_VL600= ++@@ -451,43 +451,6 @@ USB_VL600= USB_NET_CH9200= USB_NET_AQC111= + USB_RTL8153_ECM= @@ -2498,7 +3746,7 @@ index ff2ce2071f..19a60d7956 100644 +++ b/Kconfig.local -@@ -1315,117 +1315,6 @@ config BACKPORTED_USB_NET_CH9200 - config BACKPORTED_USB_NET_AQC111 -+@@ -1288,117 +1288,6 @@ config BACKPORTED_USB_NET_AQC111 ++@@ -1357,117 +1357,6 @@ config BACKPORTED_USB_NET_AQC111 + config BACKPORTED_USB_RTL8153_ECM tristate - default USB_NET_AQC111 @@ -2511,7 +3759,7 @@ index ff2ce2071f..19a60d7956 100644 --- a/Kconfig.sources +++ b/Kconfig.sources -@@ -7,9 +7,6 @@ source "$BACKPORT_DIR/net/mac80211/Kconf -+@@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/bus/mhi/Kc ++@@ -10,9 +10,6 @@ source "$BACKPORT_DIR/drivers/soc/qcom/K source "$BACKPORT_DIR/drivers/net/wireless/Kconfig" source "$BACKPORT_DIR/drivers/net/usb/Kconfig" @@ -2522,12 +3770,28 @@ index ff2ce2071f..19a60d7956 100644 -@@ -40,8 +40,6 @@ obj-y += compat/ - obj-$(CPTCFG_CFG80211) += net/wireless/ - obj-$(CPTCFG_MAC80211) += net/mac80211/ -+@@ -42,8 +42,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/ -+ obj-$(CPTCFG_QRTR) += net/qrtr/ ++@@ -43,8 +43,6 @@ obj-$(CPTCFG_QRTR) += net/qrtr/ ++ obj-$(CPTCFG_QCOM_QMI_HELPERS) += drivers/soc/qcom/ + obj-$(CPTCFG_MHI_BUS) += drivers/bus/mhi/ obj-$(CPTCFG_WLAN) += drivers/net/wireless/ -obj-$(CPTCFG_SSB) += drivers/ssb/ -obj-$(CPTCFG_BCMA) += drivers/bcma/ +diff --git a/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch b/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch +new file mode 100644 +index 0000000000..77b6e1de1c +--- /dev/null ++++ b/package/kernel/mac80211/patches/build/070-remove-broken-wext-select.patch +@@ -0,0 +1,10 @@ ++--- a/drivers/staging/rtl8723bs/Kconfig +++++ b/drivers/staging/rtl8723bs/Kconfig ++@@ -5,7 +5,6 @@ config RTL8723BS ++ depends on m ++ depends on WLAN && MMC && CFG80211 ++ depends on m ++- select CFG80211_WEXT ++ select BPAUTO_CRYPTO_LIB_ARC4 ++ help ++ This option enables support for RTL8723BS SDIO drivers, such as diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch index d358cfe367..140949f9a8 100644 --- a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -2540,8 +3804,55 @@ index d358cfe367..140949f9a8 100644 MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static const struct pci_device_id mwl8k_pci_id_table[] = { -diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch -index a35cf1875a..96b1ce77e9 100644 +diff --git a/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch +new file mode 100644 +index 0000000000..4115eeccbb +--- /dev/null ++++ b/package/kernel/mac80211/patches/mwl/900-mwifiex-increase-the-global-limit-up-to-4-SSID.patch +@@ -0,0 +1,41 @@ ++From ef8098cd6cb8b5989afef2e8461fe6ba9570a854 Mon Sep 17 00:00:00 2001 ++From: Josef Schlehofer <pepe.schlehofer@gmail.com> ++Date: Wed, 24 Nov 2021 12:47:40 +0100 ++Subject: [PATCH] mwifiex: increase the global limit up to 4 SSID ++ ++Firmware for SDIO (88W8997), which is used in Turris MOX SDIO addon [1], ++allows up to 4 SSID. Unfortunately, driver (even in mainline kernel) ++has a global limit for all Marvell cards up to 3 SSID. ++ ++Pali Rohár tested this patch and verified that the SDIO Wi-Fi addon works ++with the 4 SSID. So, let's increase the global limit from 3 to 4. ++ ++Ideally, this patch should be done differently before sending ++it to Linux kernel. It means that limit definition should be moved to ++the card-specific structure. ++ ++[1] https://docs.turris.cz/hw/mox/addons/#wi-fi-sdio ++--- ++ drivers/net/wireless/marvell/mwifiex/decl.h | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/drivers/net/wireless/marvell/mwifiex/decl.h +++++ b/drivers/net/wireless/marvell/mwifiex/decl.h ++@@ -30,7 +30,7 @@ ++ #include <net/cfg80211.h> ++ ++ #define MWIFIEX_BSS_COEX_COUNT 2 ++-#define MWIFIEX_MAX_BSS_NUM (3) +++#define MWIFIEX_MAX_BSS_NUM (4) ++ ++ #define MWIFIEX_DMA_ALIGN_SZ 64 ++ #define MWIFIEX_RX_HEADROOM 64 ++@@ -112,7 +112,7 @@ ++ #define MWIFIEX_RATE_INDEX_OFDM0 4 ++ ++ #define MWIFIEX_MAX_STA_NUM 3 ++-#define MWIFIEX_MAX_UAP_NUM 3 +++#define MWIFIEX_MAX_UAP_NUM 4 ++ #define MWIFIEX_MAX_P2P_NUM 3 ++ ++ #define MWIFIEX_A_BAND_START_FREQ 5000 +diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +index a35cf1875a..96b1ce77e9 100644 --- a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch @@ -1,6 +1,6 @@ @@ -2561,578 +3872,3298 @@ index a35cf1875a..96b1ce77e9 100644 return; priv = hw->priv; +diff --git a/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch +new file mode 100644 +index 0000000000..8fa3924e60 +--- /dev/null ++++ b/package/kernel/mac80211/patches/mwl/950-mwifiex-Print-stringified-name-of-command-in-error-l.patch +@@ -0,0 +1,189 @@ ++From f7252b1b5755150535af226e806594bbefd45e0f Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> ++Date: Sun, 26 Sep 2021 14:39:44 +0200 ++Subject: [PATCH] mwifiex: Print stringified name of command in error log ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++Failed hex command number in error log is hard to understand. ++So add also more human readable stringified command name into error log. ++ ++Signed-off-by: Pali Rohár <pali@kernel.org> ++--- ++ drivers/net/wireless/marvell/mwifiex/cmdevt.c | 96 +++++++++++++++++-- ++ drivers/net/wireless/marvell/mwifiex/main.h | 2 + ++ .../wireless/marvell/mwifiex/sta_cmdresp.c | 5 +- ++ .../net/wireless/marvell/mwifiex/uap_cmd.c | 3 +- ++ 4 files changed, 95 insertions(+), 11 deletions(-) ++ ++--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c ++@@ -28,6 +28,85 @@ ++ ++ static void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter); ++ +++const char * +++mwifiex_cmd_to_str(u16 command) +++{ +++ switch (command) { +++ case HostCmd_CMD_GET_HW_SPEC: return "GET_HW_SPEC"; +++ case HostCmd_CMD_802_11_SCAN: return "SCAN"; +++ case HostCmd_CMD_802_11_GET_LOG: return "GET_LOG"; +++ case HostCmd_CMD_MAC_MULTICAST_ADR: return "MAC_MULTICAST_ADR"; +++ case HostCmd_CMD_802_11_EEPROM_ACCESS: return "EEPROM_ACCESS"; +++ case HostCmd_CMD_802_11_ASSOCIATE: return "ASSOCIATE"; +++ case HostCmd_CMD_802_11_SNMP_MIB: return "SNMP_MIB"; +++ case HostCmd_CMD_MAC_REG_ACCESS: return "MAC_REG_ACCESS"; +++ case HostCmd_CMD_BBP_REG_ACCESS: return "BBP_REG_ACCESS"; +++ case HostCmd_CMD_RF_REG_ACCESS: return "RF_REG_ACCESS"; +++ case HostCmd_CMD_PMIC_REG_ACCESS: return "PMIC_REG_ACCESS"; +++ case HostCmd_CMD_RF_TX_PWR: return "RF_TX_PWR"; +++ case HostCmd_CMD_RF_ANTENNA: return "RF_ANTENNA"; +++ case HostCmd_CMD_802_11_DEAUTHENTICATE: return "DEAUTHENTICATE"; +++ case HostCmd_CMD_MAC_CONTROL: return "MAC_CONTROL"; +++ case HostCmd_CMD_802_11_AD_HOC_START: return "AD_HOC_START"; +++ case HostCmd_CMD_802_11_AD_HOC_JOIN: return "AD_HOC_JOIN"; +++ case HostCmd_CMD_802_11_AD_HOC_STOP: return "AD_HOC_STOP"; +++ case HostCmd_CMD_802_11_MAC_ADDRESS: return "MAC_ADDRESS"; +++ case HostCmd_CMD_802_11D_DOMAIN_INFO: return "DOMAIN_INFO"; +++ case HostCmd_CMD_802_11_KEY_MATERIAL: return "KEY_MATERIAL"; +++ case HostCmd_CMD_802_11_BG_SCAN_CONFIG: return "BG_SCAN_CONFIG"; +++ case HostCmd_CMD_802_11_BG_SCAN_QUERY: return "BG_SCAN_QUERY"; +++ case HostCmd_CMD_WMM_GET_STATUS: return "WMM_GET_STATUS"; +++ case HostCmd_CMD_802_11_SUBSCRIBE_EVENT: return "SUBSCRIBE_EVENT"; +++ case HostCmd_CMD_802_11_TX_RATE_QUERY: return "TX_RATE_QUERY"; +++ case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS: return "IBSS_COALESCING_STATUS"; +++ case HostCmd_CMD_MEM_ACCESS: return "MEM_ACCESS"; +++ case HostCmd_CMD_CFG_DATA: return "CFG_DATA"; +++ case HostCmd_CMD_VERSION_EXT: return "VERSION_EXT"; +++ case HostCmd_CMD_MEF_CFG: return "MEF_CFG"; +++ case HostCmd_CMD_RSSI_INFO: return "RSSI_INFO"; +++ case HostCmd_CMD_FUNC_INIT: return "FUNC_INIT"; +++ case HostCmd_CMD_FUNC_SHUTDOWN: return "FUNC_SHUTDOWN"; +++ case HOST_CMD_APCMD_SYS_RESET: return "SYS_RESET"; +++ case HostCmd_CMD_UAP_SYS_CONFIG: return "UAP_SYS_CONFIG"; +++ case HostCmd_CMD_UAP_BSS_START: return "UAP_BSS_START"; +++ case HostCmd_CMD_UAP_BSS_STOP: return "UAP_BSS_STOP"; +++ case HOST_CMD_APCMD_STA_LIST: return "STA_LIST"; +++ case HostCmd_CMD_UAP_STA_DEAUTH: return "UAP_STA_DEAUTH"; +++ case HostCmd_CMD_11N_CFG: return "11N_CFG"; +++ case HostCmd_CMD_11N_ADDBA_REQ: return "ADDBA_REQ"; +++ case HostCmd_CMD_11N_ADDBA_RSP: return "ADDBA_RSP"; +++ case HostCmd_CMD_11N_DELBA: return "DELBA"; +++ case HostCmd_CMD_RECONFIGURE_TX_BUFF: return "RECONFIGURE_TX_BUFF"; +++ case HostCmd_CMD_CHAN_REPORT_REQUEST: return "CHAN_REPORT_REQUEST"; +++ case HostCmd_CMD_AMSDU_AGGR_CTRL: return "AMSDU_AGGR_CTRL"; +++ case HostCmd_CMD_TXPWR_CFG: return "TXPWR_CFG"; +++ case HostCmd_CMD_TX_RATE_CFG: return "TX_RATE_CFG"; +++ case HostCmd_CMD_ROBUST_COEX: return "ROBUST_COEX"; +++ case HostCmd_CMD_802_11_PS_MODE_ENH: return "PS_MODE_ENH"; +++ case HostCmd_CMD_802_11_HS_CFG_ENH: return "HS_CFG_ENH"; +++ case HostCmd_CMD_P2P_MODE_CFG: return "P2P_MODE_CFG"; +++ case HostCmd_CMD_CAU_REG_ACCESS: return "CAU_REG_ACCESS"; +++ case HostCmd_CMD_SET_BSS_MODE: return "SET_BSS_MODE"; +++ case HostCmd_CMD_PCIE_DESC_DETAILS: return "PCIE_DESC_DETAILS"; +++ case HostCmd_CMD_802_11_SCAN_EXT: return "SCAN_EXT"; +++ case HostCmd_CMD_COALESCE_CFG: return "COALESCE_CFG"; +++ case HostCmd_CMD_MGMT_FRAME_REG: return "MGMT_FRAME_REG"; +++ case HostCmd_CMD_REMAIN_ON_CHAN: return "REMAIN_ON_CHAN"; +++ case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: return "GTK_REKEY_OFFLOAD_CFG"; +++ case HostCmd_CMD_11AC_CFG: return "11AC_CFG"; +++ case HostCmd_CMD_HS_WAKEUP_REASON: return "HS_WAKEUP_REASON"; +++ case HostCmd_CMD_TDLS_CONFIG: return "TDLS_CONFIG"; +++ case HostCmd_CMD_MC_POLICY: return "MC_POLICY"; +++ case HostCmd_CMD_TDLS_OPER: return "TDLS_OPER"; +++ case HostCmd_CMD_FW_DUMP_EVENT: return "FW_DUMP_EVENT"; +++ case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG: return "SDIO_SP_RX_AGGR_CFG"; +++ case HostCmd_CMD_STA_CONFIGURE: return "STA_CONFIGURE"; +++ case HostCmd_CMD_CHAN_REGION_CFG: return "CHAN_REGION_CFG"; +++ case HostCmd_CMD_PACKET_AGGR_CTRL: return "PACKET_AGGR_CTRL"; +++ default: return "UNKNOWN"; +++ } +++} +++ ++ /* ++ * This function initializes a command node. ++ * ++@@ -205,8 +284,8 @@ static int mwifiex_dnld_cmd_to_fw(struct ++ cmd_code != HostCmd_CMD_FUNC_SHUTDOWN && ++ cmd_code != HostCmd_CMD_FUNC_INIT) { ++ mwifiex_dbg(adapter, ERROR, ++- "DNLD_CMD: FW in reset state, ignore cmd %#x\n", ++- cmd_code); +++ "DNLD_CMD: FW in reset state, ignore cmd %s (%#x)\n", +++ mwifiex_cmd_to_str(cmd_code), cmd_code); ++ mwifiex_recycle_cmd_node(adapter, cmd_node); ++ queue_work(adapter->workqueue, &adapter->main_work); ++ return -1; ++@@ -660,8 +739,8 @@ int mwifiex_send_cmd(struct mwifiex_priv ++ /* Return error, since the command preparation failed */ ++ if (ret) { ++ mwifiex_dbg(adapter, ERROR, ++- "PREP_CMD: cmd %#x preparation failed\n", ++- cmd_no); +++ "PREP_CMD: cmd %s (%#x) preparation failed\n", +++ mwifiex_cmd_to_str(cmd_no), cmd_no); ++ mwifiex_insert_cmd_to_free_q(adapter, cmd_node); ++ return -1; ++ } ++@@ -900,8 +979,9 @@ int mwifiex_process_cmdresp(struct mwifi ++ if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { ++ if (ret) { ++ mwifiex_dbg(adapter, ERROR, ++- "%s: cmd %#x failed during\t" ++- "initialization\n", __func__, cmdresp_no); +++ "%s: cmd %s (%#x) failed during\t" +++ "initialization\n", __func__, +++ mwifiex_cmd_to_str(cmdresp_no), cmdresp_no); ++ mwifiex_init_fw_complete(adapter); ++ return -1; ++ } else if (adapter->last_init_cmd == cmdresp_no) ++@@ -1264,8 +1344,8 @@ mwifiex_process_sleep_confirm_resp(struc ++ ++ if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { ++ mwifiex_dbg(adapter, ERROR, ++- "%s: rcvd unexpected resp for cmd %#x, result = %x\n", ++- __func__, command, result); +++ "%s: rcvd unexpected resp for cmd %s (%#x), result = %x\n", +++ __func__, mwifiex_cmd_to_str(command), command, result); ++ return; ++ } ++ ++--- a/drivers/net/wireless/marvell/mwifiex/main.h +++++ b/drivers/net/wireless/marvell/mwifiex/main.h ++@@ -1106,6 +1106,8 @@ void mwifiex_cancel_all_pending_cmd(stru ++ void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter); ++ void mwifiex_cancel_scan(struct mwifiex_adapter *adapter); ++ +++const char *mwifiex_cmd_to_str(u16 command); +++ ++ void mwifiex_recycle_cmd_node(struct mwifiex_adapter *adapter, ++ struct cmd_ctrl_node *cmd_node); ++ ++--- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c ++@@ -48,8 +48,9 @@ mwifiex_process_cmdresp_error(struct mwi ++ struct host_cmd_ds_802_11_ps_mode_enh *pm; ++ ++ mwifiex_dbg(adapter, ERROR, ++- "CMD_RESP: cmd %#x error, result=%#x\n", ++- resp->command, resp->result); +++ "CMD_RESP: cmd %s (%#x) error, result=%#x\n", +++ mwifiex_cmd_to_str(le16_to_cpu(resp->command)), +++ le16_to_cpu(resp->command), le16_to_cpu(resp->result)); ++ ++ if (adapter->curr_cmd->wait_q_enabled) ++ adapter->cmd_wait_q.status = -1; ++--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +++++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c ++@@ -806,7 +806,8 @@ int mwifiex_uap_prepare_cmd(struct mwifi ++ break; ++ default: ++ mwifiex_dbg(priv->adapter, ERROR, ++- "PREP_CMD: unknown cmd %#x\n", cmd_no); +++ "PREP_CMD: unknown cmd (%s) %#x\n", +++ mwifiex_cmd_to_str(cmd_no), cmd_no); ++ return -1; ++ } ++ +diff --git a/package/kernel/mac80211/patches/rt2x00/001-rt2x00-define-RF5592-in-init_eeprom-routine.patch b/package/kernel/mac80211/patches/rt2x00/001-rt2x00-define-RF5592-in-init_eeprom-routine.patch +new file mode 100644 +index 0000000000..351e24a4d5 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/001-rt2x00-define-RF5592-in-init_eeprom-routine.patch +@@ -0,0 +1,52 @@ ++From patchwork Sat Sep 17 20:26:27 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979242 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:26:27 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 01/16] rt2x00: define RF5592 in init_eeprom routine ++Message-ID: ++ <d7eccb2c7b8ec4cd360fa2007796abffc35abb0d.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: Tomislav Požega <pozega.tomislav@gmail.com> ++ ++Fix incorrect RF value encoded in EEPROM on devices with Ralink Rt5592 ++PCIe radio (a single chip 2T2R 802.11abgn solution). ++ ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ ++ 1 file changed, 2 insertions(+) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -9435,6 +9435,8 @@ static int rt2800_init_eeprom(struct rt2 ++ rf = RF3853; ++ else if (rt2x00_rt(rt2x00dev, RT5350)) ++ rf = RF5350; +++ else if (rt2x00_rt(rt2x00dev, RT5592)) +++ rf = RF5592; ++ else ++ rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); ++ +diff --git a/package/kernel/mac80211/patches/rt2x00/002-rt2x00-add-throughput-LED-trigger.patch b/package/kernel/mac80211/patches/rt2x00/002-rt2x00-add-throughput-LED-trigger.patch +new file mode 100644 +index 0000000000..02d1f7a2e5 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/002-rt2x00-add-throughput-LED-trigger.patch +@@ -0,0 +1,76 @@ ++From patchwork Sat Sep 17 20:26:40 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979243 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:26:40 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 02/16] rt2x00: add throughput LED trigger ++Message-ID: ++ <73f5ba4134e621462a26186449400cf0c1ac1730.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: David Bauer <mail@david-bauer.net> ++ ++This adds a (currently missing) throughput LED trigger for the rt2x00 ++driver. Previously, LED triggers had to be assigned to the netdev, which ++was limited to a single VAP. ++ ++Tested-by: Christoph Krapp <achterin@googlemail.com> ++Signed-off-by: David Bauer <mail@david-bauer.net> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 18 ++++++++++++++++++ ++ 1 file changed, 18 insertions(+) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++@@ -1093,6 +1093,19 @@ static void rt2x00lib_remove_hw(struct r ++ kfree(rt2x00dev->spec.channels_info); ++ } ++ +++static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = { +++ { .throughput = 0 * 1024, .blink_time = 334 }, +++ { .throughput = 1 * 1024, .blink_time = 260 }, +++ { .throughput = 2 * 1024, .blink_time = 220 }, +++ { .throughput = 5 * 1024, .blink_time = 190 }, +++ { .throughput = 10 * 1024, .blink_time = 170 }, +++ { .throughput = 25 * 1024, .blink_time = 150 }, +++ { .throughput = 54 * 1024, .blink_time = 130 }, +++ { .throughput = 120 * 1024, .blink_time = 110 }, +++ { .throughput = 265 * 1024, .blink_time = 80 }, +++ { .throughput = 586 * 1024, .blink_time = 50 }, +++}; +++ ++ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) ++ { ++ struct hw_mode_spec *spec = &rt2x00dev->spec; ++@@ -1174,6 +1187,11 @@ static int rt2x00lib_probe_hw(struct rt2 ++ ++ #undef RT2X00_TASKLET_INIT ++ +++ ieee80211_create_tpt_led_trigger(rt2x00dev->hw, +++ IEEE80211_TPT_LEDTRIG_FL_RADIO, +++ rt2x00_tpt_blink, +++ ARRAY_SIZE(rt2x00_tpt_blink)); +++ ++ /* ++ * Register HW. ++ */ diff --git a/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch b/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch -index a50a195285..96eeb37dc6 100644 +deleted file mode 100644 +index a50a195285..0000000000 --- a/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch -+++ b/package/kernel/mac80211/patches/rt2x00/002-rt2x00-define-RF5592-in-init_eeprom-routine.patch -@@ -40,7 +40,7 @@ Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> - - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ /dev/null +@@ -1,51 +0,0 @@ +-From patchwork Thu Dec 27 14:05:26 2018 +-Content-Type: text/plain; charset="utf-8" +-MIME-Version: 1.0 +-Content-Transfer-Encoding: 8bit +-X-Patchwork-Submitter: Tom Psyborg <pozega.tomislav@gmail.com> +-X-Patchwork-Id: 10743707 +-X-Patchwork-Delegate: kvalo@adurom.com +-From: =?utf-8?q?Tomislav_Po=C5=BEega?= <pozega.tomislav@gmail.com> +-To: linux-wireless@vger.kernel.org +-Cc: kvalo@codeaurora.org, hauke@hauke-m.de, nbd@nbd.name, +- john@phrozen.org, sgruszka@redhat.com, daniel@makrotopia.org +-Subject: [PATCH 2/2] rt2x00: define RF5592 in init_eeprom routine +-Date: Thu, 27 Dec 2018 15:05:26 +0100 +-Message-Id: <1545919526-4074-2-git-send-email-pozega.tomislav@gmail.com> +-X-Mailer: git-send-email 1.7.0.4 +-In-Reply-To: <1545919526-4074-1-git-send-email-pozega.tomislav@gmail.com> +-References: <1545919526-4074-1-git-send-email-pozega.tomislav@gmail.com> +-MIME-Version: 1.0 +-Sender: linux-wireless-owner@vger.kernel.org +-Precedence: bulk +-List-ID: <linux-wireless.vger.kernel.org> +-X-Mailing-List: linux-wireless@vger.kernel.org +-X-Virus-Scanned: ClamAV using ClamSMTP +- +-This patch fixes following crash on Linksys EA2750 during 5GHz wifi +-init: +- +-[ 7.955153] rt2800pci 0000:01:00.0: card - bus=0x1, slot = 0x0 irq=4 +-[ 7.962259] rt2800pci 0000:01:00.0: loaded eeprom from mtd device "Factory" +-[ 7.969435] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 5592, rev 0222 detected +-[ 7.977348] ieee80211 phy0: rt2800_init_eeprom: Error - Invalid RF chipset 0x0000 detected +-[ 7.985793] ieee80211 phy0: rt2x00lib_probe_dev: Error - Failed to allocate device +-[ 7.993569] CPU 0 Unable to handle kernel paging request at virtual address 00000024, epc == 800c8f54, ra == 80249ff8 +-[ 8.004408] Oops[#1]: +- +-Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> +---- +- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ +- 1 files changed, 2 insertions(+), 0 deletions(-) +- +---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -9416,6 +9416,8 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -9435,6 +9435,8 @@ static int rt2800_init_eeprom(struct rt2 - rf = RF3853; - else if (rt2x00_rt(rt2x00dev, RT5350)) - rf = RF5350; -diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -index e74d9a9aa0..afe8cea205 100644 ---- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -+++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch -@@ -1,6 +1,6 @@ - --- a/local-symbols - +++ b/local-symbols --@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE= -+@@ -322,6 +322,7 @@ RT2X00_LIB_FIRMWARE= - RT2X00_LIB_CRYPTO= - RT2X00_LIB_LEDS= - RT2X00_LIB_DEBUGFS= -@@ -105,7 +105,7 @@ - .drv_init_registers = rt2800mmio_init_registers, - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -694,6 +694,7 @@ enum rt2x00_capability_flags { -+@@ -703,6 +703,7 @@ enum rt2x00_capability_flags { - REQUIRE_HT_TX_DESC, - REQUIRE_PS_AUTOWAKE, - REQUIRE_DELAYED_RFKILL, -@@ -113,7 +113,7 @@ - - /* - * Capabilities --@@ -970,6 +971,11 @@ struct rt2x00_dev { -+@@ -980,6 +981,11 @@ struct rt2x00_dev { - const struct firmware *fw; - - /* -@@ -127,7 +127,7 @@ - DECLARE_KFIFO_PTR(txstatus_fifo, u32); - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1406,6 +1406,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de -+@@ -1401,6 +1401,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de - INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); - INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); - -@@ -138,7 +138,7 @@ - /* - * Let the driver probe the device to detect the capabilities. - */ --@@ -1549,6 +1553,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ -+@@ -1541,6 +1545,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ - * Free the driver data. - */ - kfree(rt2x00dev->drv_data); -diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -index 6a8e594d5e..ffee2189d2 100644 ---- a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -+++ b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch -@@ -12,7 +12,7 @@ - #endif /* _RT2X00_PLATFORM_H */ - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1012,6 +1012,22 @@ static int rt2x00lib_probe_hw_modes(stru -+@@ -1007,6 +1007,22 @@ static int rt2x00lib_probe_hw_modes(stru - unsigned int num_rates; - unsigned int i; - -@@ -37,7 +37,7 @@ - num_rates += 4; - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -399,6 +399,7 @@ struct hw_mode_spec { -+@@ -408,6 +408,7 @@ struct hw_mode_spec { - unsigned int supported_bands; - #define SUPPORT_BAND_2GHZ 0x00000001 - #define SUPPORT_BAND_5GHZ 0x00000002 -diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -index b5b2c61037..37553bb80a 100644 ---- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -+++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch -@@ -1,19 +1,18 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80 -+@@ -989,6 +989,12 @@ static void rt2x00lib_rate(struct ieee80 - - void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) - { - + struct rt2x00_platform_data *pdata; -- const char *mac_addr; +- rf = RF3853; +- else if (rt2x00_rt(rt2x00dev, RT5350)) +- rf = RF5350; +-+ else if (rt2x00_rt(rt2x00dev, RT5592)) +-+ rf = RF5592; +- else +- rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); - -++ - + pdata = rt2x00dev->dev->platform_data; - + if (pdata && pdata->mac_address) - + ether_addr_copy(eeprom_mac_addr, pdata->mac_address); - + -- mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); -- if (!IS_ERR(mac_addr)) -- ether_addr_copy(eeprom_mac_addr, mac_addr); -+ of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); -+ -+ if (!is_valid_ether_addr(eeprom_mac_addr)) { - --- a/include/linux/rt2x00_platform.h - +++ b/include/linux/rt2x00_platform.h - @@ -14,6 +14,7 @@ -diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -index ff8b2c947b..6211809c0a 100644 ---- a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -+++ b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1016,6 +1016,16 @@ static int rt2x00lib_probe_hw_modes(stru -+@@ -1012,6 +1012,16 @@ static int rt2x00lib_probe_hw_modes(stru - struct ieee80211_rate *rates; - unsigned int num_rates; - unsigned int i; -diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -index 039c6f6afc..d78b76d7f5 100644 ---- a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -+++ b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch -@@ -8,7 +8,7 @@ - - #include "rt2x00.h" - #include "rt2800lib.h" --@@ -9530,6 +9531,17 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -9549,6 +9550,17 @@ static int rt2800_init_eeprom(struct rt2 - rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); - rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); - -diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -index 88d6dd559b..0da9356e0c 100644 ---- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -+++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1344,7 +1344,7 @@ static inline void rt2x00lib_set_if_comb -+@@ -1340,7 +1340,7 @@ static inline void rt2x00lib_set_if_comb - */ - if_limit = &rt2x00dev->if_limits_ap; - if_limit->max = rt2x00dev->ops->max_ap_intf; -diff --git a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch -index fca1fb2cd4..6e6564f870 100644 ---- a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch -+++ b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch -@@ -11,7 +11,7 @@ Tested-by: Christoph Krapp <achterin@googlemail.com> +diff --git a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/003-rt2x00-add-support-for-external-PA-on-MT7620.patch +similarity index 58% +rename from package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch +rename to package/kernel/mac80211/patches/rt2x00/003-rt2x00-add-support-for-external-PA-on-MT7620.patch +index 20452cd8a7..216f583063 100644 +--- a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch ++++ b/package/kernel/mac80211/patches/rt2x00/003-rt2x00-add-support-for-external-PA-on-MT7620.patch +@@ -1,22 +1,42 @@ +-From 9782a7f7488443568fa4d6088b73c9aff7eb8510 Mon Sep 17 00:00:00 2001 ++From patchwork Sat Sep 17 20:26:55 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979244 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:26:55 +0100 + From: Daniel Golle <daniel@makrotopia.org> +-Date: Wed, 19 Apr 2017 16:14:53 +0200 +-Subject: [PATCH] rt2x00: add support for external PA on MT7620 +-To: Stanislaw Gruszka <sgruszka@redhat.com> +-Cc: Helmut Schaa <helmut.schaa@googlemail.com>, +- linux-wireless@vger.kernel.org, +- Kalle Valo <kvalo@codeaurora.org> +-Content-Type: text/plain; charset="UTF-8" +-Content-Transfer-Encoding: quoted-printable ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 03/16] rt2x00: add support for external PA on MT7620 ++Message-ID: ++ <af2c68ff831816a86fc39b0c10911c129a1f03dc.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1129,6 +1129,19 @@ static void rt2x00lib_remove_hw(struct r -+@@ -1125,6 +1125,19 @@ static void rt2x00lib_remove_hw(struct r - kfree(rt2x00dev->spec.channels_info); - } - -@@ -31,7 +31,7 @@ Tested-by: Christoph Krapp <achterin@googlemail.com> - static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) - { - struct hw_mode_spec *spec = &rt2x00dev->spec; --@@ -1210,6 +1223,10 @@ static int rt2x00lib_probe_hw(struct rt2 -+@@ -1206,6 +1219,10 @@ static int rt2x00lib_probe_hw(struct rt2 - - #undef RT2X00_TASKLET_INIT +-Signed-off-by: Daniel Golle <daniel@makrotopia.org> +-Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> +-[pozega.tomislav@gmail.com: use chanreg and dccal helpers.] ++Implement support for external PA connected to MT7620A. + ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++[pozega.tomislav@gmail.com: use chanreg and dccal helpers.] ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> + --- +- drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 + +- drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++- +- 2 files changed, 70 insertions(+), 1 deletion(-) ++ drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 + ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 52 ++++++++++++++++++- ++ 2 files changed, 52 insertions(+), 1 deletion(-) + + --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -24,21 +44,19 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> + #define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) + #define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) + #define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) +-+#define EEPROM_NIC_CONF2_EXTERNAL_PA FIELD16(0xc000) +++#define EEPROM_NIC_CONF2_EXTERNAL_PA FIELD16(0x8000) -diff --git a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch -index 20452cd8a7..8814c02532 100644 ---- a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch -+++ b/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch -@@ -30,7 +30,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> + /* * EEPROM LNA --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4356,6 +4356,45 @@ static void rt2800_config_channel(struct -+@@ -4369,6 +4369,45 @@ static void rt2800_config_channel(struct ++@@ -4368,6 +4368,43 @@ static void rt2800_config_channel(struct rt2800_iq_calibrate(rt2x00dev, rf->channel); } -@@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> + + if (rt2x00_rt(rt2x00dev, RT6352)) { + + if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, + + &rt2x00dev->cap_flags)) { +-+ rt2x00_warn(rt2x00dev, "Using incomplete support for " \ +-+ "external PA\n"); + + reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); + + reg |= 0x00000101; + + rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); +@@ -76,7 +94,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> bbp = rt2800_bbp_read(rt2x00dev, 4); rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); rt2800_bbp_write(rt2x00dev, 4, bbp); -@@ -9559,7 +9598,8 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -9578,7 +9617,8 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -9566,7 +9603,8 @@ static int rt2800_init_eeprom(struct rt2 */ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); -@@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> +@@ -86,19 +104,19 @@ Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com> if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) __set_bit(CAPABILITY_EXTERNAL_PA_TX0, -@@ -9570,6 +9610,18 @@ static int rt2800_init_eeprom(struct rt2 -+@@ -9589,6 +9629,18 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -9577,6 +9615,18 @@ static int rt2800_init_eeprom(struct rt2 &rt2x00dev->cap_flags); } -diff --git a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch -index 6be847478e..b798dcc6d8 100644 ---- a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch -+++ b/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -8419,6 +8419,56 @@ static void rt2800_init_rfcsr_5592(struc -+@@ -8438,6 +8438,56 @@ static void rt2800_init_rfcsr_5592(struc - rt2800_led_open_drain_enable(rt2x00dev); - } - -@@ -57,7 +57,7 @@ - static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, - bool set_bw, bool is_ht40) - { --@@ -9026,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -9045,6 +9095,7 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); - rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); - -diff --git a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch b/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch -index 3ed0ff7ef5..cf21c39a6c 100644 ---- a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch -+++ b/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -8469,6 +8469,155 @@ static void rt2800_rf_self_txdc_cal(stru -+@@ -8488,6 +8488,155 @@ static void rt2800_rf_self_txdc_cal(stru - rt2x00_info(rt2x00dev, "RF Tx self calibration end\n"); - } - -@@ -156,7 +156,7 @@ - static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, - bool set_bw, bool is_ht40) - { --@@ -9076,6 +9225,7 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -9095,6 +9244,7 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); - rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); - -diff --git a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch -index 77be986d18..1f8684b0bf 100644 ---- a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch -+++ b/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF2); + + + + if (rt2x00_rt(rt2x00dev, RT6352) && eeprom != 0 && eeprom != 0xffff) { +-+ if (rt2x00_get_field16(eeprom, +-+ EEPROM_NIC_CONF2_EXTERNAL_PA)) { +-+ __set_bit(CAPABILITY_EXTERNAL_PA_TX0, +-+ &rt2x00dev->cap_flags); +-+ __set_bit(CAPABILITY_EXTERNAL_PA_TX1, +-+ &rt2x00dev->cap_flags); +++ if (!rt2x00_get_field16(eeprom, +++ EEPROM_NIC_CONF2_EXTERNAL_PA)) { +++ __clear_bit(CAPABILITY_EXTERNAL_PA_TX0, +++ &rt2x00dev->cap_flags); +++ __clear_bit(CAPABILITY_EXTERNAL_PA_TX1, +++ &rt2x00dev->cap_flags); + + } + + } + + +diff --git a/package/kernel/mac80211/patches/rt2x00/004-rt2x00-move-up-and-reuse-busy-wait-functions.patch b/package/kernel/mac80211/patches/rt2x00/004-rt2x00-move-up-and-reuse-busy-wait-functions.patch +new file mode 100644 +index 0000000000..da453074a1 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/004-rt2x00-move-up-and-reuse-busy-wait-functions.patch +@@ -0,0 +1,178 @@ ++From patchwork Sat Sep 17 20:27:10 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979245 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:27:10 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 04/16] rt2x00: move up and reuse busy wait functions ++Message-ID: ++ <3fdb9dc15e76a9f9c1948b4a3a1308a7a5677bb8.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Move bbp_ready and rf_ready busy wait functions up in the code so they ++can more easily be used. Allow specifying register mask in rf_ready ++function which is useful for calibration routines which will be added ++in follow-up commits. ++ ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 99 +++++++++---------- ++ 1 file changed, 46 insertions(+), 53 deletions(-) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -2143,6 +2143,48 @@ void rt2800_config_erp(struct rt2x00_dev ++ } ++ EXPORT_SYMBOL_GPL(rt2800_config_erp); ++ +++static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev, +++ const struct rt2x00_field32 mask) +++{ +++ unsigned int i; +++ u32 reg; +++ +++ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { +++ reg = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +++ if (!rt2x00_get_field32(reg, mask)) +++ return 0; +++ +++ udelay(REGISTER_BUSY_DELAY); +++ } +++ +++ rt2x00_err(rt2x00dev, "BBP/RF register access failed, aborting\n"); +++ return -EACCES; +++} +++ +++static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) +++{ +++ unsigned int i; +++ u8 value; +++ +++ /* +++ * BBP was enabled after firmware was loaded, +++ * but we need to reactivate it now. +++ */ +++ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); +++ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); +++ msleep(1); +++ +++ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { +++ value = rt2800_bbp_read(rt2x00dev, 0); +++ if ((value != 0xff) && (value != 0x00)) +++ return 0; +++ udelay(REGISTER_BUSY_DELAY); +++ } +++ +++ rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); +++ return -EACCES; +++} +++ ++ static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev) ++ { ++ u32 reg; ++@@ -3799,10 +3841,9 @@ static void rt2800_config_alc(struct rt2 ++ struct ieee80211_channel *chan, ++ int power_level) { ++ u16 eeprom, target_power, max_power; ++- u32 mac_sys_ctrl, mac_status; +++ u32 mac_sys_ctrl; ++ u32 reg; ++ u8 bbp; ++- int i; ++ ++ /* hardware unit is 0.5dBm, limited to 23.5dBm */ ++ power_level *= 2; ++@@ -3838,16 +3879,8 @@ static void rt2800_config_alc(struct rt2 ++ /* Disable Tx/Rx */ ++ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); ++ /* Check MAC Tx/Rx idle */ ++- for (i = 0; i < 10000; i++) { ++- mac_status = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); ++- if (mac_status & 0x3) ++- usleep_range(50, 200); ++- else ++- break; ++- } ++- ++- if (i == 10000) ++- rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) +++ rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n"); ++ ++ if (chan->center_freq > 2457) { ++ bbp = rt2800_bbp_read(rt2x00dev, 30); ++@@ -6249,46 +6282,6 @@ static int rt2800_init_registers(struct ++ return 0; ++ } ++ ++-static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) ++-{ ++- unsigned int i; ++- u32 reg; ++- ++- for (i = 0; i < REGISTER_BUSY_COUNT; i++) { ++- reg = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); ++- if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY)) ++- return 0; ++- ++- udelay(REGISTER_BUSY_DELAY); ++- } ++- ++- rt2x00_err(rt2x00dev, "BBP/RF register access failed, aborting\n"); ++- return -EACCES; ++-} ++- ++-static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) ++-{ ++- unsigned int i; ++- u8 value; ++- ++- /* ++- * BBP was enabled after firmware was loaded, ++- * but we need to reactivate it now. ++- */ ++- rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); ++- rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); ++- msleep(1); ++- ++- for (i = 0; i < REGISTER_BUSY_COUNT; i++) { ++- value = rt2800_bbp_read(rt2x00dev, 0); ++- if ((value != 0xff) && (value != 0x00)) ++- return 0; ++- udelay(REGISTER_BUSY_DELAY); ++- } ++- ++- rt2x00_err(rt2x00dev, "BBP register access failed, aborting\n"); ++- return -EACCES; ++-} ++ ++ static void rt2800_bbp4_mac_if_ctrl(struct rt2x00_dev *rt2x00dev) ++ { ++@@ -9110,7 +9103,7 @@ int rt2800_enable_radio(struct rt2x00_de ++ /* ++ * Wait BBP/RF to wake up. ++ */ ++- if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev))) +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) ++ return -EIO; ++ ++ /* +diff --git a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/005-rt2x00-add-RF-self-TXDC-calibration-for-MT7620.patch +similarity index 51% +rename from package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch +rename to package/kernel/mac80211/patches/rt2x00/005-rt2x00-add-RF-self-TXDC-calibration-for-MT7620.patch +index 6be847478e..4e98d6a375 100644 +--- a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/005-rt2x00-add-RF-self-TXDC-calibration-for-MT7620.patch +@@ -1,6 +1,48 @@ ++From patchwork Sat Sep 17 20:27:26 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979246 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:27:26 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 05/16] rt2x00: add RF self TXDC calibration for MT7620 ++Message-ID: ++ <dbb6e5a0c12d6101477bd09e83253091d21512c9.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: Tomislav Požega <pozega.tomislav@gmail.com> ++ ++Add TX self calibration based on mtk driver. ++ ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++v2: use ++i instead of i = i + 1 in loops ++ ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 48 +++++++++++++++++++ ++ 1 file changed, 48 insertions(+) ++ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -8419,6 +8419,56 @@ static void rt2800_init_rfcsr_5592(struc ++@@ -8428,6 +8428,53 @@ static void rt2800_init_rfcsr_5592(struc + rt2800_led_open_drain_enable(rt2x00dev); + } + +@@ -10,7 +52,6 @@ + + u32 mac0518, mac051c, mac0528, mac052c; + + u8 i; + + +-+ rt2x00_info(rt2x00dev, "RF Tx self calibration start\n"); + + mac0518 = rt2800_register_read(rt2x00dev, RF_CONTROL0); + + mac051c = rt2800_register_read(rt2x00dev, RF_BYPASS0); + + mac0528 = rt2800_register_read(rt2x00dev, RF_CONTROL2); +@@ -27,19 +68,19 @@ + + rfb7r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1); + + + + rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, 0x4); +-+ for (i = 0; i < 100; i = i + 1) { +-+ udelay(50); +++ for (i = 0; i < 100; ++i) { +++ usleep_range(50, 100); + + rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1); +-+ if((rfvalue & 0x04) != 0x4) +++ if ((rfvalue & 0x04) != 0x4) + + break; + + } + + rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rfb5r1_org); + + + + rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, 0x4); +-+ for (i = 0; i < 100; i = i + 1) { +-+ udelay(50); +++ for (i = 0; i < 100; ++i) { +++ usleep_range(50, 100); + + rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1); +-+ if((rfvalue & 0x04) != 0x4) +++ if ((rfvalue & 0x04) != 0x4) + + break; + + } + + rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, rfb7r1_org); +@@ -50,14 +91,12 @@ + + rt2800_register_write(rt2x00dev, RF_BYPASS0, mac051c); + + rt2800_register_write(rt2x00dev, RF_CONTROL2, mac0528); + + rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c); +-+ +-+ rt2x00_info(rt2x00dev, "RF Tx self calibration end\n"); + +} + + + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9026,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9035,6 +9082,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + +diff --git a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch b/package/kernel/mac80211/patches/rt2x00/006-rt2x00-add-r-calibration-for-MT7620.patch +similarity index 66% +rename from package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch +rename to package/kernel/mac80211/patches/rt2x00/006-rt2x00-add-r-calibration-for-MT7620.patch +index 3ed0ff7ef5..7c69970166 100644 +--- a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/006-rt2x00-add-r-calibration-for-MT7620.patch +@@ -1,14 +1,68 @@ ++From patchwork Sat Sep 17 20:27:41 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979247 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:27:41 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 06/16] rt2x00: add r calibration for MT7620 ++Message-ID: ++ <e0c34f233089bec4eb73826bc4f512166ee25934.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: Tomislav Požega <pozega.tomislav@gmail.com> ++ ++Add r calibration code as found in mtk driver. ++ ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++v2: use rt2800_wait_bbp_rf_ready() ++ ++ drivers/net/wireless/ralink/rt2x00/rt2800.h | 2 + ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 133 ++++++++++++++++++ ++ 2 files changed, 135 insertions(+) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h ++@@ -1016,6 +1016,8 @@ ++ */ ++ #define MAC_STATUS_CFG 0x1200 ++ #define MAC_STATUS_CFG_BBP_RF_BUSY FIELD32(0x00000003) +++#define MAC_STATUS_CFG_BBP_RF_BUSY_TX FIELD32(0x00000001) +++#define MAC_STATUS_CFG_BBP_RF_BUSY_RX FIELD32(0x00000002) ++ ++ /* ++ * PWR_PIN_CFG: + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -8469,6 +8469,155 @@ static void rt2800_rf_self_txdc_cal(stru +- rt2x00_info(rt2x00dev, "RF Tx self calibration end\n"); ++@@ -8475,6 +8475,138 @@ static void rt2800_rf_self_txdc_cal(stru ++ rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c); + } + + +static int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2) + +{ +-+ int calcode; +-+ calcode = ((d2 - d1) * 1000) / 43; +-+ if ((calcode%10) >= 5) +++ int calcode = ((d2 - d1) * 1000) / 43; +++ +++ if ((calcode % 10) >= 5) + + calcode += 10; + + calcode = (calcode / 10); + + +@@ -28,8 +82,7 @@ + + char d1 = 0, d2 = 0; + + u8 rfvalue; + + u32 MAC_RF_BYPASS0, MAC_RF_CONTROL0, MAC_PWR_PIN_CFG; +-+ u32 maccfg, macstatus; +-+ int i; +++ u32 maccfg; + + + + saverfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1); + + saverfb0r34 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 34); +@@ -53,30 +106,14 @@ + + maccfg &= (~0x04); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg); + + +-+ for (i = 0; i < 10000; i++) { +-+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macstatus & 0x1) +-+ udelay(50); +-+ else +-+ break; +-+ } +-+ +-+ if (i == 10000) +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX))) + + rt2x00_warn(rt2x00dev, "Wait MAC Tx Status to MAX !!!\n"); + + + + maccfg = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + maccfg &= (~0x04); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, maccfg); + + +-+ for (i = 0; i < 10000; i++) { +-+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macstatus & 0x2) +-+ udelay(50); +-+ else +-+ break; +-+ } +-+ +-+ if (i == 10000) +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX))) + + rt2x00_warn(rt2x00dev, "Wait MAC Rx Status to MAX !!!\n"); + + + + rfvalue = (MAC_RF_BYPASS0 | 0x3004); +@@ -98,7 +135,7 @@ + + + + rt2800_bbp_write(rt2x00dev, 47, 0x04); + + rt2800_bbp_write(rt2x00dev, 22, 0x80); +-+ udelay(100); +++ usleep_range(100, 200); + + bytevalue = rt2800_bbp_read(rt2x00dev, 49); + + if (bytevalue > 128) + + d1 = bytevalue - 256; +@@ -108,7 +145,7 @@ + + rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x01); + + + + rt2800_bbp_write(rt2x00dev, 22, 0x80); +-+ udelay(100); +++ usleep_range(100, 200); + + bytevalue = rt2800_bbp_read(rt2x00dev, 49); + + if (bytevalue > 128) + + d2 = bytevalue - 256; +@@ -156,7 +193,7 @@ + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9076,6 +9225,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9082,6 +9214,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + +diff --git a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/007-rt2x00-add-RXDCOC-calibration-for-MT7620.patch +similarity index 50% +rename from package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch +rename to package/kernel/mac80211/patches/rt2x00/007-rt2x00-add-RXDCOC-calibration-for-MT7620.patch +index 77be986d18..8da41e875a 100644 +--- a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch ++++ b/package/kernel/mac80211/patches/rt2x00/007-rt2x00-add-RXDCOC-calibration-for-MT7620.patch +@@ -1,13 +1,54 @@ ++From patchwork Sat Sep 17 20:27:56 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979248 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:27:56 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 07/16] rt2x00: add RXDCOC calibration for MT7620 ++Message-ID: ++ <850b30f652e88de30d79e968af4eb47aa5bc2511.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: Tomislav Požega <pozega.tomislav@gmail.com> ++ ++Add RXDCOC calibration code from mtk driver. ++ ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++[fixed typo reported by Serge Vasilugin <vasilugin@yandex.ru>] ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 60 +++++++++++++++++++ ++ 1 file changed, 60 insertions(+) ++ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8618,6 +8618,70 @@ static void rt2800_r_calibration(struct -+@@ -8637,6 +8637,70 @@ static void rt2800_r_calibration(struct ++@@ -8607,6 +8607,65 @@ static void rt2800_r_calibration(struct rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG); } -@@ -71,7 +71,7 @@ + +static void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev) + +{ + + u8 bbpreg = 0; +-+ u32 macvalue = 0, macvalue1 = 0; +++ u32 macvalue = 0; + + u8 saverfb0r2, saverfb5r4, saverfb7r4, rfvalue; + + int i; + + +@@ -24,15 +65,10 @@ + + macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x8); + + +-+ for (i = 0; i < 10000; i++) { +-+ macvalue1 = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macvalue1 & 0x1) +-+ udelay(50); +-+ else +-+ break; +-+ } +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX))) +++ rt2x00_warn(rt2x00dev, "RF TX busy in RX RXDCOC calibration\n"); + + +-+ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0); +++ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4); + + saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4); + + saverfb5r4 = saverfb5r4 & (~0x40); + + saverfb7r4 = saverfb7r4 & (~0x40); +@@ -49,9 +85,9 @@ + + + + for (i = 0; i < 10000; i++) { + + bbpreg = rt2800_bbp_read(rt2x00dev, 159); +-+ if ((bbpreg & 0x40)==0) +++ if ((bbpreg & 0x40) == 0) + + break; +-+ udelay(50); +++ usleep_range(50, 100); + + } + + + + bbpreg = rt2800_bbp_read(rt2x00dev, 159); +@@ -71,7 +107,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9227,6 +9291,7 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -9246,6 +9310,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9216,6 +9275,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_r_calibration(rt2x00dev); rt2800_rf_self_txdc_cal(rt2x00dev); -diff --git a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch b/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch -index 7352ad036c..98f2e245ce 100644 +diff --git a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch b/package/kernel/mac80211/patches/rt2x00/008-rt2x00-add-RXIQ-calibration-for-MT7620.patch +similarity index 63% +rename from package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch +rename to package/kernel/mac80211/patches/rt2x00/008-rt2x00-add-RXIQ-calibration-for-MT7620.patch +index 7352ad036c..dc516da43a 100644 --- a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch -+++ b/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch -@@ -1,6 +1,6 @@ ++++ b/package/kernel/mac80211/patches/rt2x00/008-rt2x00-add-RXIQ-calibration-for-MT7620.patch +@@ -1,17 +1,62 @@ ++From patchwork Sat Sep 17 20:28:10 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979249 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:28:10 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 08/16] rt2x00: add RXIQ calibration for MT7620 ++Message-ID: ++ <033a39a697d51f6df258acea4c33608e0944fe4c.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: Tomislav Požega <pozega.tomislav@gmail.com> ++ ++Add RXIQ calibration found in mtk driver. With old openwrt builds this ++gets us ~8Mbps more of RX bandwidth (test with iPA/eLNA layout). ++ ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++v2: use rt2800_wait_bbp_rf_ready(), fix indentation ++ ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 375 ++++++++++++++++++ ++ 1 file changed, 375 insertions(+) ++ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8682,6 +8682,384 @@ static void rt2800_rxdcoc_calibration(st -+@@ -8701,6 +8701,384 @@ static void rt2800_rxdcoc_calibration(st ++@@ -8666,6 +8666,380 @@ static void rt2800_rxdcoc_calibration(st rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2); } -@@ -385,7 +385,7 @@ +-+static u32 rt2800_do_sqrt_accumulation(u32 si) { +++static u32 rt2800_do_sqrt_accumulation(u32 si) +++{ + + u32 root, root_pre, bit; + + char i; +++ + + bit = 1 << 15; + + root = 0; + + for (i = 15; i >= 0; i = i - 1) { + + root_pre = root + bit; +-+ if ((root_pre*root_pre) <= si) +++ if ((root_pre * root_pre) <= si) + + root = root_pre; + + bit = bit >> 1; + + } +@@ -19,7 +64,8 @@ + + return root; + +} + + +-+static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev) { +++static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev) +++{ + + u8 rfb0r1, rfb0r2, rfb0r42; + + u8 rfb4r0, rfb4r19; + + u8 rfb5r3, rfb5r4, rfb5r17, rfb5r18, rfb5r19, rfb5r20; +@@ -43,8 +89,8 @@ + + u32 orig_RF_BYPASS1 = 0; + + u32 orig_RF_CONTROL3 = 0; + + u32 orig_RF_BYPASS3 = 0; +-+ u32 macstatus, bbpval1 = 0; +-+ u8 rf_vga_table[] = {0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; +++ u32 bbpval1 = 0; +++ static const u8 rf_vga_table[] = {0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}; + + + + savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + orig_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0); +@@ -59,16 +105,8 @@ + + + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x0); + + +-+ for (i = 0; i < 10000; i++) { +-+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macstatus & 0x3) +-+ udelay(50); +-+ else +-+ break; +-+ } +-+ +-+ if (i == 10000) +-+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) +++ rt2x00_warn(rt2x00dev, "Timeout waiting for MAC status in RXIQ calibration\n"); + + + + bbpval = bbp4 & (~0x18); + + bbpval = bbp4 | 0x00; +@@ -165,7 +203,7 @@ + + rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006); + + udelay(1); + + +-+ bbpval = bbp1 & (~ 0x18); +++ bbpval = bbp1 & (~0x18); + + bbpval = bbpval | 0x00; + + rt2800_bbp_write(rt2x00dev, 1, bbpval); + + +@@ -184,132 +222,133 @@ + + rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006); + + udelay(1); + + +-+ bbpval = bbp1 & (~ 0x18); +++ bbpval = bbp1 & (~0x18); + + bbpval = bbpval | 0x08; + + rt2800_bbp_write(rt2x00dev, 1, bbpval); + + + + rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x01); + + } +-+ udelay(500); +++ usleep_range(500, 1500); + + + + vga_idx = 0; +-+ while (vga_idx < 11) { +-+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rf_vga_table[vga_idx]); +-+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rf_vga_table[vga_idx]); +-+ +-+ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x93); +-+ +-+ for (i = 0; i < 10000; i++) { +-+ bbpval = rt2800_bbp_read(rt2x00dev, 159); +-+ if ((bbpval & 0xff) == 0x93) +-+ udelay(50); +-+ else +-+ break; +-+ } +-+ +-+ if ((bbpval & 0xff) == 0x93) { +-+ rt2x00_warn(rt2x00dev, "Fatal Error: Calibration doesn't finish"); +-+ goto restore_value; +-+ } +++ while (vga_idx < 11) { +++ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rf_vga_table[vga_idx]); +++ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rf_vga_table[vga_idx]); + + +-+ for (i = 0; i < 5; i++) { +-+ u32 bbptemp = 0; +-+ u8 value = 0; +-+ int result = 0; +-+ +-+ rt2800_bbp_write(rt2x00dev, 158, 0x1e); +-+ rt2800_bbp_write(rt2x00dev, 159, i); +-+ rt2800_bbp_write(rt2x00dev, 158, 0x22); +-+ value = rt2800_bbp_read(rt2x00dev, 159); +-+ bbptemp = bbptemp + (value << 24); +-+ rt2800_bbp_write(rt2x00dev, 158, 0x21); +-+ value = rt2800_bbp_read(rt2x00dev, 159); +-+ bbptemp = bbptemp + (value << 16); +-+ rt2800_bbp_write(rt2x00dev, 158, 0x20); +-+ value = rt2800_bbp_read(rt2x00dev, 159); +-+ bbptemp = bbptemp + (value << 8); +-+ rt2800_bbp_write(rt2x00dev, 158, 0x1f); +-+ value = rt2800_bbp_read(rt2x00dev, 159); +-+ bbptemp = bbptemp + value; +-+ +-+ if ((i < 2) && (bbptemp & 0x800000)) +-+ result = (bbptemp & 0xffffff) - 0x1000000; +-+ else if (i == 4) +-+ result = bbptemp; +-+ else +-+ result = bbptemp; +-+ +-+ if (i == 0) +-+ mi = result/4096; +-+ else if (i == 1) +-+ mq = result/4096; +-+ else if (i == 2) +-+ si = bbptemp/4096; +-+ else if (i == 3) +-+ sq = bbptemp/4096; +-+ else +-+ riq = result/4096; +-+ } +-+ +-+ bbpval1 = si - mi*mi; +-+ rt2x00_dbg(rt2x00dev, "RXIQ si=%d, sq=%d, riq=%d, bbpval %d, vga_idx %d", si, sq, riq, bbpval1, vga_idx); +++ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x93); + + +-+ if (bbpval1 >= (100*100)) +++ for (i = 0; i < 10000; i++) { +++ bbpval = rt2800_bbp_read(rt2x00dev, 159); +++ if ((bbpval & 0xff) == 0x93) +++ usleep_range(50, 100); +++ else + + break; +++ } + + +-+ if (bbpval1 <= 100) +-+ vga_idx = vga_idx + 9; +-+ else if (bbpval1 <= 158) +-+ vga_idx = vga_idx + 8; +-+ else if (bbpval1 <= 251) +-+ vga_idx = vga_idx + 7; +-+ else if (bbpval1 <= 398) +-+ vga_idx = vga_idx + 6; +-+ else if (bbpval1 <= 630) +-+ vga_idx = vga_idx + 5; +-+ else if (bbpval1 <= 1000) +-+ vga_idx = vga_idx + 4; +-+ else if (bbpval1 <= 1584) +-+ vga_idx = vga_idx + 3; +-+ else if (bbpval1 <= 2511) +-+ vga_idx = vga_idx + 2; +++ if ((bbpval & 0xff) == 0x93) { +++ rt2x00_warn(rt2x00dev, "Fatal Error: Calibration doesn't finish"); +++ goto restore_value; +++ } +++ for (i = 0; i < 5; i++) { +++ u32 bbptemp = 0; +++ u8 value = 0; +++ int result = 0; +++ +++ rt2800_bbp_write(rt2x00dev, 158, 0x1e); +++ rt2800_bbp_write(rt2x00dev, 159, i); +++ rt2800_bbp_write(rt2x00dev, 158, 0x22); +++ value = rt2800_bbp_read(rt2x00dev, 159); +++ bbptemp = bbptemp + (value << 24); +++ rt2800_bbp_write(rt2x00dev, 158, 0x21); +++ value = rt2800_bbp_read(rt2x00dev, 159); +++ bbptemp = bbptemp + (value << 16); +++ rt2800_bbp_write(rt2x00dev, 158, 0x20); +++ value = rt2800_bbp_read(rt2x00dev, 159); +++ bbptemp = bbptemp + (value << 8); +++ rt2800_bbp_write(rt2x00dev, 158, 0x1f); +++ value = rt2800_bbp_read(rt2x00dev, 159); +++ bbptemp = bbptemp + value; +++ +++ if (i < 2 && (bbptemp & 0x800000)) +++ result = (bbptemp & 0xffffff) - 0x1000000; +++ else if (i == 4) +++ result = bbptemp; +++ else +++ result = bbptemp; +++ +++ if (i == 0) +++ mi = result / 4096; +++ else if (i == 1) +++ mq = result / 4096; +++ else if (i == 2) +++ si = bbptemp / 4096; +++ else if (i == 3) +++ sq = bbptemp / 4096; + + else +-+ vga_idx = vga_idx + 1; +++ riq = result / 4096; + + } + + +-+ sigma_i = rt2800_do_sqrt_accumulation(100*(si - mi*mi)); +-+ sigma_q = rt2800_do_sqrt_accumulation(100*(sq - mq*mq)); +-+ r_iq = 10*(riq-(mi*mq)); +++ bbpval1 = si - mi * mi; +++ rt2x00_dbg(rt2x00dev, +++ "RXIQ si=%d, sq=%d, riq=%d, bbpval %d, vga_idx %d", +++ si, sq, riq, bbpval1, vga_idx); +++ +++ if (bbpval1 >= (100 * 100)) +++ break; +++ +++ if (bbpval1 <= 100) +++ vga_idx = vga_idx + 9; +++ else if (bbpval1 <= 158) +++ vga_idx = vga_idx + 8; +++ else if (bbpval1 <= 251) +++ vga_idx = vga_idx + 7; +++ else if (bbpval1 <= 398) +++ vga_idx = vga_idx + 6; +++ else if (bbpval1 <= 630) +++ vga_idx = vga_idx + 5; +++ else if (bbpval1 <= 1000) +++ vga_idx = vga_idx + 4; +++ else if (bbpval1 <= 1584) +++ vga_idx = vga_idx + 3; +++ else if (bbpval1 <= 2511) +++ vga_idx = vga_idx + 2; +++ else +++ vga_idx = vga_idx + 1; +++ } +++ +++ sigma_i = rt2800_do_sqrt_accumulation(100 * (si - mi * mi)); +++ sigma_q = rt2800_do_sqrt_accumulation(100 * (sq - mq * mq)); +++ r_iq = 10 * (riq - (mi * mq)); + + + + rt2x00_dbg(rt2x00dev, "Sigma_i=%d, Sigma_q=%d, R_iq=%d", sigma_i, sigma_q, r_iq); + + +-+ if (((sigma_i <= 1400 ) && (sigma_i >= 1000)) +-+ && ((sigma_i - sigma_q) <= 112) +-+ && ((sigma_i - sigma_q) >= -112) +-+ && ((mi <= 32) && (mi >= -32)) +-+ && ((mq <= 32) && (mq >= -32))) { +-+ r_iq = 10*(riq-(mi*mq)); +-+ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq); +-+ +-+ g_rx = (1000 * sigma_q) / sigma_i; +-+ g_imb = ((-2) * 128 * (1000 - g_rx)) / (1000 + g_rx); +-+ ph_rx = (r_iq * 2292) / (sigma_i * sigma_q); +-+ rt2x00_info(rt2x00dev, "RXIQ G_imb=%d, Ph_rx=%d\n", g_imb, ph_rx); +-+ +-+ if ((ph_rx > 20) || (ph_rx < -20)) { +-+ ph_rx = 0; +-+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL"); +-+ } +++ if (sigma_i <= 1400 && sigma_i >= 1000 && +++ (sigma_i - sigma_q) <= 112 && +++ (sigma_i - sigma_q) >= -112 && +++ mi <= 32 && mi >= -32 && +++ mq <= 32 && mq >= -32) { +++ r_iq = 10 * (riq - (mi * mq)); +++ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", +++ sigma_i, sigma_q, r_iq); +++ +++ g_rx = (1000 * sigma_q) / sigma_i; +++ g_imb = ((-2) * 128 * (1000 - g_rx)) / (1000 + g_rx); +++ ph_rx = (r_iq * 2292) / (sigma_i * sigma_q); +++ +++ if (ph_rx > 20 || ph_rx < -20) { +++ ph_rx = 0; +++ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL"); +++ } + + +-+ if ((g_imb > 12) || (g_imb < -12)) { +-+ g_imb = 0; +-+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL"); +-+ } +++ if (g_imb > 12 || g_imb < -12) { +++ g_imb = 0; +++ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL"); + + } +-+ else { +++ } else { + + g_imb = 0; + + ph_rx = 0; +-+ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq); +++ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", +++ sigma_i, sigma_q, r_iq); + + rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL"); + + } + + +@@ -385,7 +424,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9294,6 +9672,7 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -9313,6 +9691,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9278,6 +9652,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rxdcoc_calibration(rt2x00dev); rt2800_bw_filter_calibration(rt2x00dev, true); rt2800_bw_filter_calibration(rt2x00dev, false); -diff --git a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch -index fe0961baa7..6a685f80ab 100644 +diff --git a/package/kernel/mac80211/patches/rt2x00/009-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/009-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch +new file mode 100644 +index 0000000000..6b27f6a705 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/009-rt2x00-don-t-run-Rt5592-IQ-calibration-on-MT7620.patch +@@ -0,0 +1,52 @@ ++From patchwork Sat Sep 17 20:28:29 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979250 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:28:29 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 09/16] rt2x00: don't run Rt5592 IQ calibration on MT7620 ++Message-ID: ++ <31a1c34ddbd296b82f38c18c9ae7339059215fdc.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++The function rt2800_iq_calibrate is intended for Rt5592 only. ++Don't call it for MT7620 which has it's own calibration functions. ++ ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++--- ++v2: test for RT5592 instead of !RT6352 ++ ++ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- ++ 1 file changed, 2 insertions(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -4398,7 +4398,8 @@ static void rt2800_config_channel(struct ++ reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); ++ ++- rt2800_iq_calibrate(rt2x00dev, rf->channel); +++ if (rt2x00_rt(rt2x00dev, RT5592)) +++ rt2800_iq_calibrate(rt2x00dev, rf->channel); ++ } ++ ++ if (rt2x00_rt(rt2x00dev, RT6352)) { +diff --git a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-add-TX-LOFT-calibration-for-MT7620.patch +similarity index 84% +rename from package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch +rename to package/kernel/mac80211/patches/rt2x00/010-rt2x00-add-TX-LOFT-calibration-for-MT7620.patch +index fe0961baa7..bb01ff1dca 100644 --- a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch -+++ b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch -@@ -1,6 +1,6 @@ ++++ b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-add-TX-LOFT-calibration-for-MT7620.patch +@@ -1,10 +1,56 @@ ++From patchwork Sat Sep 17 20:28:43 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 8bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979251 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:28:43 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 10/16] rt2x00: add TX LOFT calibration for MT7620 ++Message-ID: ++ <d9295a9138a1f552b648aacb84e1419d38f5c896.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++From: Tomislav Požega <pozega.tomislav@gmail.com> ++ ++Add TX LOFT calibration from mtk driver. ++ ++Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++--- ++v2: use helper functions, make tables static const, remove useless ++ debug prints ++v3: don't export function not used anywhere else ++Reported-by: kernel test robot <lkp@intel.com> ++ ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 902 ++++++++++++++++++ ++ .../net/wireless/ralink/rt2x00/rt2800lib.h | 10 + ++ 2 files changed, 912 insertions(+) ++ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -9060,6 +9060,943 @@ restore_value: -+@@ -9079,6 +9079,943 @@ restore_value: ++@@ -9041,6 +9041,907 @@ restore_value: rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl); } -@@ -944,7 +944,7 @@ - static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, - bool set_bw, bool is_ht40) - { --@@ -9672,6 +10609,7 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -9691,6 +10628,7 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rxdcoc_calibration(rt2x00dev); - rt2800_bw_filter_calibration(rt2x00dev, true); - rt2800_bw_filter_calibration(rt2x00dev, false); -diff --git a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -index 3de00b2267..40b20ec594 100644 ---- a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -+++ b/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch -@@ -14,7 +14,7 @@ - */ - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -3685,14 +3685,16 @@ static void rt2800_config_channel_rf7620 -+@@ -3698,14 +3698,16 @@ static void rt2800_config_channel_rf7620 - rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); - rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); - -@@ -39,7 +39,7 @@ - - rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); - rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, --@@ -3726,18 +3728,23 @@ static void rt2800_config_channel_rf7620 -+@@ -3739,18 +3741,23 @@ static void rt2800_config_channel_rf7620 - rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); - } - -@@ -73,7 +73,7 @@ - - if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { - if (conf_is_ht40(conf)) { --@@ -3837,25 +3844,29 @@ static void rt2800_config_alc(struct rt2 -+@@ -3850,25 +3857,29 @@ static void rt2800_config_alc(struct rt2 - if (i == 10000) - rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); - -@@ -121,7 +121,7 @@ - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); - - rt2800_vco_calibration(rt2x00dev); --@@ -5887,18 +5898,33 @@ static int rt2800_init_registers(struct -+@@ -5906,18 +5917,33 @@ static int rt2800_init_registers(struct - } else if (rt2x00_rt(rt2x00dev, RT5350)) { - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); - } else if (rt2x00_rt(rt2x00dev, RT6352)) { -@@ -167,7 +167,7 @@ - reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); - rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); - rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); --@@ -7042,14 +7068,16 @@ static void rt2800_init_bbp_6352(struct -+@@ -7061,14 +7087,16 @@ static void rt2800_init_bbp_6352(struct - rt2800_bbp_write(rt2x00dev, 188, 0x00); - rt2800_bbp_write(rt2x00dev, 189, 0x00); - -@@ -192,7 +192,7 @@ - - /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ - rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); --@@ -10388,31 +10416,36 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -10407,31 +10435,36 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); - rt2800_rfcsr_write(rt2x00dev, 43, 0x00); - -@@ -254,7 +254,7 @@ - - /* Initialize RF channel register to default value */ - rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); --@@ -10478,63 +10511,71 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -10497,63 +10530,71 @@ static void rt2800_init_rfcsr_6352(struc - - rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); - -@@ -383,7 +383,7 @@ - - /* Initialize RF DC calibration register to default value */ - rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); --@@ -10597,12 +10638,17 @@ static void rt2800_init_rfcsr_6352(struc -+@@ -10616,12 +10657,17 @@ static void rt2800_init_rfcsr_6352(struc - rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); - rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); - -diff --git a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch b/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch -deleted file mode 100644 -index 31a7baeee7..0000000000 ---- a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch -+++ /dev/null -@@ -1,183 +0,0 @@ ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -1238,6 +1238,8 @@ void rt2800_watchdog(struct rt2x00_dev * -- if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) -- return; -- --+ rt2800_update_survey(rt2x00dev); +-+static void rt2800_rf_configstore(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_reg_record[][13], u8 chain) +++static void rt2800_rf_configstore(struct rt2x00_dev *rt2x00dev, +++ struct rf_reg_pair rf_reg_record[][13], u8 chain) + +{ + + u8 rfvalue = 0; + + +@@ -116,13 +162,11 @@ + + rf_reg_record[CHAIN_1][12].value = rfvalue; + + } else { + + rt2x00_warn(rt2x00dev, "Unknown chain = %u\n", chain); +-+ return; + + } -+ -- queue_for_each(rt2x00dev, queue) { -- switch (queue->qid) { -- case QID_AC_VO: --@@ -1274,6 +1276,18 @@ void rt2800_watchdog(struct rt2x00_dev * -- } -- EXPORT_SYMBOL_GPL(rt2800_watchdog); -- --+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev) --+{ --+ struct ieee80211_channel *chan = rt2x00dev->hw->conf.chandef.chan; --+ struct rt2x00_chan_survey *chan_survey = --+ &rt2x00dev->chan_survey[chan->hw_value]; +-+ return; + +} + + +-+static void rt2800_rf_configrecover(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_record[][13]) +++static void rt2800_rf_configrecover(struct rt2x00_dev *rt2x00dev, +++ struct rf_reg_pair rf_record[][13]) + +{ + + u8 chain_index = 0, record_index = 0; + + u8 bank = 0, rf_register = 0, value = 0; +@@ -133,11 +177,10 @@ + + rf_register = rf_record[chain_index][record_index].reg; + + value = rf_record[chain_index][record_index].value; + + rt2800_rfcsr_write_bank(rt2x00dev, bank, rf_register, value); +-+ rt2x00_dbg(rt2x00dev, "bank: %d, rf_register: %d, value: %x\n", bank, rf_register, value); +++ rt2x00_dbg(rt2x00dev, "bank: %d, rf_register: %d, value: %x\n", +++ bank, rf_register, value); + + } + + } -+ --+ chan_survey->time_idle += rt2800_register_read(rt2x00dev, CH_IDLE_STA); --+ chan_survey->time_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA); --+ chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); --+} --+EXPORT_SYMBOL_GPL(rt2800_update_survey); +-+ return; + +} + + + +static void rt2800_setbbptonegenerator(struct rt2x00_dev *rt2x00dev) +@@ -155,15 +198,13 @@ + + rt2800_bbp_write(rt2x00dev, 159, 0x3F); + + + + rt2800_bbp_write(rt2x00dev, 244, 0x40); -+ -- static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, -- unsigned int index) -- { --@@ -12199,26 +12213,30 @@ int rt2800_get_survey(struct ieee80211_h -- { -- struct rt2x00_dev *rt2x00dev = hw->priv; -- struct ieee80211_conf *conf = &hw->conf; --- u32 idle, busy, busy_ext; --+ struct rt2x00_chan_survey *chan_survey = --+ &rt2x00dev->chan_survey[idx]; --+ enum nl80211_band band = NL80211_BAND_2GHZ; -- --- if (idx != 0) --+ if (idx >= rt2x00dev->bands[band].n_channels) { --+ idx -= rt2x00dev->bands[band].n_channels; --+ band = NL80211_BAND_5GHZ; --+ } +-+ return; + +} + + + +static u32 rt2800_do_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx, u8 read_neg) + +{ + + u32 macvalue = 0; + + int fftout_i = 0, fftout_q = 0; +-+ u32 ptmp=0, pint = 0; +++ u32 ptmp = 0, pint = 0; + + u8 bbp = 0; + + u8 tidxi; + + +@@ -173,7 +214,7 @@ + + bbp = 0x9b; + + + + while (bbp == 0x9b) { +-+ udelay(10); +++ usleep_range(10, 50); + + bbp = rt2800_bbp_read(rt2x00dev, 159); + + bbp = bbp & 0xff; + + } +@@ -218,10 +259,11 @@ + + return pint; + +} + + +-+static u32 rt2800_read_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx) { +++static u32 rt2800_read_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx) +++{ + + u32 macvalue = 0; + + int fftout_i = 0, fftout_q = 0; +-+ u32 ptmp=0, pint = 0; +++ u32 ptmp = 0, pint = 0; + + + + rt2800_bbp_write(rt2x00dev, 158, 0xBA); + + rt2800_bbp_write(rt2x00dev, 159, tidx); +@@ -237,7 +279,6 @@ + + ptmp = (fftout_i * fftout_i); + + ptmp = ptmp + (fftout_q * fftout_q); + + pint = ptmp; +-+ rt2x00_info(rt2x00dev, "I = %d, Q = %d, power = %x\n", fftout_i, fftout_q, pint); + + + + return pint; + +} +@@ -251,18 +292,17 @@ + + rt2800_bbp_write(rt2x00dev, 159, bbp); + + + + if (ch_idx == 0) +-+ bbp = (iorq == 0) ? 0xb1: 0xb2; +++ bbp = (iorq == 0) ? 0xb1 : 0xb2; + + else +-+ bbp = (iorq == 0) ? 0xb8: 0xb9; +++ bbp = (iorq == 0) ? 0xb8 : 0xb9; + + + + rt2800_bbp_write(rt2x00dev, 158, bbp); + + bbp = dc; + + rt2800_bbp_write(rt2x00dev, 159, bbp); -+ --+ if (idx >= rt2x00dev->bands[band].n_channels) -- return -ENOENT; -- --- survey->channel = conf->chandef.chan; --+ if (idx == 0) --+ rt2800_update_survey(rt2x00dev); -- --- idle = rt2800_register_read(rt2x00dev, CH_IDLE_STA); --- busy = rt2800_register_read(rt2x00dev, CH_BUSY_STA); --- busy_ext = rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); --- --- if (idle || busy) { --- survey->filled = SURVEY_INFO_TIME | --- SURVEY_INFO_TIME_BUSY | --- SURVEY_INFO_TIME_EXT_BUSY; --- --- survey->time = (idle + busy) / 1000; --- survey->time_busy = busy / 1000; --- survey->time_ext_busy = busy_ext / 1000; --- } --+ survey->channel = &rt2x00dev->bands[band].channels[idx]; +-+ return; + +} + + +-+static void rt2800_loft_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc_idx, u8 dc_result[][RF_ALC_NUM][2]) +++static void rt2800_loft_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, +++ u8 alc_idx, u8 dc_result[][RF_ALC_NUM][2]) + +{ + + u32 p0 = 0, p1 = 0, pf = 0; + + char idx0 = 0, idx1 = 0; +@@ -276,8 +316,6 @@ + + + + for (bidx = 5; bidx >= 0; bidx--) { + + for (iorq = 0; iorq <= 1; iorq++) { +-+ rt2x00_dbg(rt2x00dev, "\n========================================================\n"); +-+ + + if (idxf[iorq] == 0x20) { + + idx0 = 0x20; + + p0 = pf; +@@ -288,16 +326,17 @@ + + p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0); + + } + + +-+ idx1 = idxf[iorq] + ((bidx == 5) ? 0 : ibit); +++ idx1 = idxf[iorq] + (bidx == 5 ? 0 : ibit); + + idx1 = idx1 & 0x3F; + + rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx1); + + p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0); + + +-+ rt2x00_dbg(rt2x00dev, "alc=%u, IorQ=%u, idx_final=%2x\n", alc_idx, iorq, idxf[iorq]); +-+ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pf=%x, idx_0=%x, idx_1=%x, ibit=%x !\n", p0, p1, pf, idx0, idx1, ibit); +++ rt2x00_dbg(rt2x00dev, "alc=%u, IorQ=%u, idx_final=%2x\n", +++ alc_idx, iorq, idxf[iorq]); +++ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pf=%x, idx_0=%x, idx_1=%x, ibit=%x\n", +++ p0, p1, pf, idx0, idx1, ibit); + + +-+ if ((bidx != 5) && (pf <= p0) && (pf < p1)) { +-+ pf = pf; +++ if (bidx != 5 && pf <= p0 && pf < p1) { + + idxf[iorq] = idxf[iorq]; + + } else if (p0 < p1) { + + pf = p0; +@@ -306,17 +345,15 @@ + + pf = p1; + + idxf[iorq] = idx1 & 0x3F; + + } +-+ rt2x00_dbg(rt2x00dev, "IorQ=%u, idx_final[%u]:%x, pf:%8x\n", iorq, iorq, idxf[iorq], pf); +++ rt2x00_dbg(rt2x00dev, "IorQ=%u, idx_final[%u]:%x, pf:%8x\n", +++ iorq, iorq, idxf[iorq], pf); + + + + rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idxf[iorq]); -+ --+ survey->filled = SURVEY_INFO_TIME | --+ SURVEY_INFO_TIME_BUSY | --+ SURVEY_INFO_TIME_EXT_BUSY; + + } + + ibit = ibit >> 1; + + } + + dc_result[ch_idx][alc_idx][0] = idxf[0]; + + dc_result[ch_idx][alc_idx][1] = idxf[1]; -+ --+ survey->time = div_u64(chan_survey->time_idle + chan_survey->time_busy, 1000); --+ survey->time_busy = div_u64(chan_survey->time_busy, 1000); --+ survey->time_ext_busy = div_u64(chan_survey->time_ext_busy, 1000); -- -- if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) -- survey->filled |= SURVEY_INFO_IN_USE; ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h --@@ -243,6 +243,7 @@ bool rt2800_txstatus_timeout(struct rt2x -- bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev); -- -- void rt2800_watchdog(struct rt2x00_dev *rt2x00dev); --+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev); -- -- void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); -- void rt2800_clear_beacon(struct queue_entry *entry); ----- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c --@@ -360,6 +360,7 @@ static const struct rt2x00lib_ops rt2800 -- .gain_calibration = rt2800_gain_calibration, -- .vco_calibration = rt2800_vco_calibration, -- .watchdog = rt2800_watchdog, --+ .update_survey = rt2800_update_survey, -- .start_queue = rt2800mmio_start_queue, -- .kick_queue = rt2800mmio_kick_queue, -- .stop_queue = rt2800mmio_stop_queue, ----- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c --@@ -214,6 +214,7 @@ static const struct rt2x00lib_ops rt2800 -- .gain_calibration = rt2800_gain_calibration, -- .vco_calibration = rt2800_vco_calibration, -- .watchdog = rt2800_watchdog, --+ .update_survey = rt2800_update_survey, -- .start_queue = rt2800mmio_start_queue, -- .kick_queue = rt2800mmio_kick_queue, -- .stop_queue = rt2800mmio_stop_queue, ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -183,6 +183,15 @@ struct rf_channel { -- }; -- -- /* --+ * Information structure for channel survey. --+ */ --+struct rt2x00_chan_survey { --+ u64 time_idle; --+ u64 time_busy; --+ u64 time_ext_busy; --+}; +-+ return; + +} + + + +static void rt2800_iq_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 *ges, u8 *pes) +@@ -334,26 +371,25 @@ + + u8 bbp = 0; + + char bidx; + + +-+ rt2x00_info(rt2x00dev, "IQCalibration Start!\n"); + + for (bidx = 5; bidx >= 1; bidx--) { + + for (gop = 0; gop < 2; gop++) { +-+ rt2x00_dbg(rt2x00dev, "\n========================================================\n"); +-+ +-+ if ((gop == 1) || (bidx < 4)) { +++ if (gop == 1 || bidx < 4) { + + if (gop == 0) + + iq_err = gerr; + + else + + iq_err = perr; + + + + first_search = (gop == 0) ? (bidx == 3) : (bidx == 5); +-+ touch_neg_max = (gop) ? ((iq_err & 0x0F) == 0x08) : ((iq_err & 0x3F) == 0x20); +++ touch_neg_max = (gop) ? ((iq_err & 0x0F) == 0x08) : +++ ((iq_err & 0x3F) == 0x20); + + + + if (touch_neg_max) { + + p0 = pf; + + idx0 = iq_err; + + } else { + + idx0 = iq_err - ibit; +-+ bbp = (ch_idx == 0) ? ((gop == 0) ? 0x28 : 0x29): ((gop == 0) ? 0x46 : 0x47); +++ bbp = (ch_idx == 0) ? ((gop == 0) ? 0x28 : 0x29) : +++ ((gop == 0) ? 0x46 : 0x47); + + + + rt2800_bbp_write(rt2x00dev, 158, bbp); + + rt2800_bbp_write(rt2x00dev, 159, idx0); +@@ -364,26 +400,30 @@ + + idx1 = iq_err + (first_search ? 0 : ibit); + + idx1 = (gop == 0) ? (idx1 & 0x0F) : (idx1 & 0x3F); + + +-+ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47; +++ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : +++ (gop == 0) ? 0x46 : 0x47; + + + + rt2800_bbp_write(rt2x00dev, 158, bbp); + + rt2800_bbp_write(rt2x00dev, 159, idx1); + + + + p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1); + + +-+ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pwer_final=%x, idx0=%x, idx1=%x, iq_err=%x, gop=%d, ibit=%x !\n", p0, p1, pf, idx0, idx1, iq_err, gop, ibit); +-+ +-+ if ((!first_search) && (pf <= p0) && (pf < p1)) { +-+ pf = pf; +-+ } else if (p0 < p1) { +-+ pf = p0; +-+ iq_err = idx0; +-+ } else { +-+ pf = p1; +-+ iq_err = idx1; +++ rt2x00_dbg(rt2x00dev, +++ "p0=%x, p1=%x, pwer_final=%x, idx0=%x, idx1=%x, iq_err=%x, gop=%d, ibit=%x\n", +++ p0, p1, pf, idx0, idx1, iq_err, gop, ibit); +++ +++ if (!(!first_search && pf <= p0 && pf < p1)) { +++ if (p0 < p1) { +++ pf = p0; +++ iq_err = idx0; +++ } else { +++ pf = p1; +++ iq_err = idx1; +++ } + + } + + +-+ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47; +++ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : +++ (gop == 0) ? 0x46 : 0x47; + + + + rt2800_bbp_write(rt2x00dev, 158, bbp); + + rt2800_bbp_write(rt2x00dev, 159, iq_err); +@@ -393,8 +433,8 @@ + + else + + perr = iq_err; + + +-+ rt2x00_dbg(rt2x00dev, "IQCalibration pf=%8x (%2x, %2x) !\n", pf, gerr & 0x0F, perr & 0x3F); -+ --+/* -- * Channel information structure -- */ -- struct channel_info { --@@ -567,6 +576,7 @@ struct rt2x00lib_ops { -- * Data queue handlers. -- */ -- void (*watchdog) (struct rt2x00_dev *rt2x00dev); --+ void (*update_survey) (struct rt2x00_dev *rt2x00dev); -- void (*start_queue) (struct data_queue *queue); -- void (*kick_queue) (struct data_queue *queue); -- void (*stop_queue) (struct data_queue *queue); --@@ -755,6 +765,7 @@ struct rt2x00_dev { -- */ -- struct ieee80211_hw *hw; -- struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; --+ struct rt2x00_chan_survey *chan_survey; -- enum nl80211_band curr_band; -- int curr_freq; -- ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1057,6 +1057,12 @@ static int rt2x00lib_probe_hw_modes(stru -- if (!rates) -- goto exit_free_channels; -- --+ rt2x00dev->chan_survey = --+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey), --+ GFP_KERNEL); --+ if (!rt2x00dev->chan_survey) --+ goto exit_free_rates; +++ rt2x00_dbg(rt2x00dev, "IQCalibration pf=%8x (%2x, %2x) !\n", +++ pf, gerr & 0x0F, perr & 0x3F); + + } + + } + + +@@ -423,25 +463,21 @@ + + rt2800_bbp_write(rt2x00dev, 159, pef & 0x3F); + + + + p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1); +-+ if ((gef == gsta) && (pef == psta)) { +++ if (gef == gsta && pef == psta) { + + pf = p1; + + gerr = gef; + + perr = pef; +-+ } +-+ else if (pf > p1){ +++ } else if (pf > p1) { + + pf = p1; + + gerr = gef; + + perr = pef; + + } +-+ rt2x00_dbg(rt2x00dev, "Fine IQCalibration p1=%8x pf=%8x (%2x, %2x) !\n", p1, pf, gef & 0x0F, pef & 0x3F); +++ rt2x00_dbg(rt2x00dev, "Fine IQCalibration p1=%8x pf=%8x (%2x, %2x) !\n", +++ p1, pf, gef & 0x0F, pef & 0x3F); + + } + + + + ges[ch_idx] = gerr & 0x0F; + + pes[ch_idx] = perr & 0x3F; -+ -- /* -- * Initialize Rate list. -- */ --@@ -1108,6 +1114,8 @@ static int rt2x00lib_probe_hw_modes(stru -- -- return 0; -- --+ exit_free_rates: --+ kfree(rates); -- exit_free_channels: -- kfree(channels); -- rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n"); ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c --@@ -317,6 +317,15 @@ int rt2x00mac_config(struct ieee80211_hw -- return 0; -- -- /* --+ * To provide correct survey data for survey-based ACS algorithm --+ * we have to save survey data for current channel before switching. --+ */ --+ if (rt2x00dev->ops->lib->update_survey && --+ (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { --+ rt2x00dev->ops->lib->update_survey(rt2x00dev); --+ } +-+ rt2x00_info(rt2x00dev, "IQCalibration Done! CH = %u, (gain=%2x, phase=%2x)\n", ch_idx, gerr & 0x0F, perr & 0x3F); -+ --+ /* -- * Some configuration parameters (e.g. channel and antenna values) can -- * only be set when the radio is enabled, but do require the RX to -- * be off. During this period we should keep link tuning enabled, +-+ return; + +} + + + +static void rt2800_rf_aux_tx0_loopback(struct rt2x00_dev *rt2x00dev) +@@ -478,9 +514,9 @@ + + rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, 0x20); + +} + + +-+void rt2800_loft_iq_calibration(struct rt2x00_dev *rt2x00dev) +++static void rt2800_loft_iq_calibration(struct rt2x00_dev *rt2x00dev) + +{ +-+ rf_reg_pair rf_store[CHAIN_NUM][13]; +++ struct rf_reg_pair rf_store[CHAIN_NUM][13]; + + u32 macorg1 = 0; + + u32 macorg2 = 0; + + u32 macorg3 = 0; +@@ -489,7 +525,7 @@ + + u32 orig528 = 0; + + u32 orig52c = 0; + + +-+ u32 savemacsysctrl = 0, mtxcycle = 0; +++ u32 savemacsysctrl = 0; + + u32 macvalue = 0; + + u32 mac13b8 = 0; + + u32 p0 = 0, p1 = 0; +@@ -498,11 +534,8 @@ + + u8 rfvalue; + + u8 loft_dc_search_result[CHAIN_NUM][RF_ALC_NUM][2]; + + u8 ger[CHAIN_NUM], per[CHAIN_NUM]; +-+ u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c}; +-+ u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F}; + + + + u8 vga_gain[] = {14, 14}; +-+ u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08}; + + u8 bbp = 0, ch_idx = 0, rf_alc_idx = 0, idx = 0; + + u8 bbpr30, rfb0r39, rfb0r42; + + u8 bbpr1; +@@ -510,6 +543,11 @@ + + u8 bbpr241, bbpr242; + + u8 count_step; + + +++ static const u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c}; +++ static const u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, +++ 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F}; +++ static const u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08}; +++ + + savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG); + + macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0); +@@ -524,29 +562,18 @@ + + macvalue &= (~0x04); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue); + + +-+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) { +-+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macvalue & 0x01) +-+ udelay(50); +-+ else +-+ break; +-+ } +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX))) +++ rt2x00_warn(rt2x00dev, "RF TX busy in LOFT IQ calibration\n"); + + + + macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + macvalue &= (~0x08); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue); + + +-+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) { +-+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macvalue & 0x02) +-+ udelay(50); +-+ else +-+ break; +-+ } +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX))) +++ rt2x00_warn(rt2x00dev, "RF RX busy in LOFT IQ calibration\n"); + + +-+ for (ch_idx = 0; ch_idx < 2; ch_idx++) { +++ for (ch_idx = 0; ch_idx < 2; ch_idx++) + + rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx); +-+ } + + + + bbpr30 = rt2800_bbp_read(rt2x00dev, 30); + + rfb0r39 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 39); +@@ -561,7 +588,7 @@ + + + + rt2800_setbbptonegenerator(rt2x00dev); + + +-+ for (ch_idx = 0; ch_idx < 2; ch_idx ++) { +++ for (ch_idx = 0; ch_idx < 2; ch_idx++) { + + rt2800_bbp_write(rt2x00dev, 23, 0x00); + + rt2800_bbp_write(rt2x00dev, 24, 0x00); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00); +@@ -571,18 +598,17 @@ + + rt2800_register_write(rt2x00dev, 0x13b8, 0x10); + + udelay(1); + + +-+ if (ch_idx == 0) { +++ if (ch_idx == 0) + + rt2800_rf_aux_tx0_loopback(rt2x00dev); +-+ } else { +++ else + + rt2800_rf_aux_tx1_loopback(rt2x00dev); +-+ } +++ + + udelay(1); + + +-+ if (ch_idx == 0) { +++ if (ch_idx == 0) + + rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004); +-+ } else { +++ else + + rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004); +-+ } + + + + rt2800_bbp_write(rt2x00dev, 158, 0x05); + + rt2800_bbp_write(rt2x00dev, 159, 0x00); +@@ -608,7 +634,8 @@ + + + + if (rf_alc_idx == 0) { + + rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x21); +-+ for (;vga_gain[ch_idx] > 0;vga_gain[ch_idx] = vga_gain[ch_idx] - 2) { +++ for (; vga_gain[ch_idx] > 0; +++ vga_gain[ch_idx] = vga_gain[ch_idx] - 2) { + + rfvalue = rfvga_gain_table[vga_gain[ch_idx]]; + + rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue); + + rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue); +@@ -618,19 +645,19 @@ + + rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x21); + + p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0); + + rt2x00_dbg(rt2x00dev, "LOFT AGC %d %d\n", p0, p1); +-+ if ((p0 < 7000*7000) && (p1 < (7000*7000))) { +++ if ((p0 < 7000 * 7000) && (p1 < (7000 * 7000))) + + break; +-+ } + + } + + + + rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00); + + rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00); + + +-+ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]); +++ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n", vga_gain[ch_idx], +++ rfvga_gain_table[vga_gain[ch_idx]]); + + + + if (vga_gain[ch_idx] < 0) + + vga_gain[ch_idx] = 0; +-+ } +++ } + + + + rfvalue = rfvga_gain_table[vga_gain[ch_idx]]; + + +@@ -644,7 +671,7 @@ + + for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) { + + for (idx = 0; idx < 4; idx++) { + + rt2800_bbp_write(rt2x00dev, 158, 0xB0); +-+ bbp = (idx<<2) + rf_alc_idx; +++ bbp = (idx << 2) + rf_alc_idx; + + rt2800_bbp_write(rt2x00dev, 159, bbp); + + rt2x00_dbg(rt2x00dev, " ALC %2x,", bbp); + + +@@ -705,8 +732,6 @@ + + rt2800_register_write(rt2x00dev, RF_BYPASS2, orig52c); + + rt2800_register_write(rt2x00dev, 0x13b8, mac13b8); + + +-+ rt2x00_info(rt2x00dev, "LOFT Calibration Done!\n"); +-+ + + savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG); + + macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0); +@@ -723,24 +748,16 @@ + + macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + macvalue &= (~0x04); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue); +-+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) { +-+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macvalue & 0x01) +-+ udelay(50); +-+ else +-+ break; +-+ } +++ +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_TX))) +++ rt2x00_warn(rt2x00dev, "RF TX busy in LOFT IQ calibration\n"); + + + + macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL); + + macvalue &= (~0x08); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue); +-+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) { +-+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG); +-+ if (macvalue & 0x02) +-+ udelay(50); +-+ else +-+ break; +-+ } +++ +++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY_RX))) +++ rt2x00_warn(rt2x00dev, "RF RX busy in LOFT IQ calibration\n"); + + + + if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) { + + rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000101); +@@ -776,9 +793,8 @@ + + + + rt2800_register_write(rt2x00dev, 0x13b8, 0x00000010); + + +-+ for (ch_idx = 0; ch_idx < 2; ch_idx++) { +++ for (ch_idx = 0; ch_idx < 2; ch_idx++) + + rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx); +-+ } + + + + rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x3B); + + rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x3B); +@@ -788,7 +804,7 @@ + + rt2800_bbp_write(rt2x00dev, 158, 0xB0); + + rt2800_bbp_write(rt2x00dev, 159, 0x80); + + +-+ for (ch_idx = 0; ch_idx < 2; ch_idx ++) { +++ for (ch_idx = 0; ch_idx < 2; ch_idx++) { + + rt2800_bbp_write(rt2x00dev, 23, 0x00); + + rt2800_bbp_write(rt2x00dev, 24, 0x00); + + +@@ -831,7 +847,7 @@ + + count_step = 2; + + } + + +-+ for (;vga_gain[ch_idx] < 19; vga_gain[ch_idx]=(vga_gain[ch_idx] + count_step)) { +++ for (; vga_gain[ch_idx] < 19; vga_gain[ch_idx] = (vga_gain[ch_idx] + count_step)) { + + rfvalue = rfvga_gain_table[vga_gain[ch_idx]]; + + rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue); + + rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue); +@@ -840,37 +856,35 @@ + + rt2800_bbp_write(rt2x00dev, 158, bbp); + + rt2800_bbp_write(rt2x00dev, 159, 0x00); + + p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0); +-+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) { +++ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) + + p0_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A); +-+ } + + + + bbp = (ch_idx == 0) ? 0x29 : 0x47; + + rt2800_bbp_write(rt2x00dev, 158, bbp); + + rt2800_bbp_write(rt2x00dev, 159, 0x21); + + p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0); +-+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) { +++ if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) + + p1_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A); +-+ } + + + + rt2x00_dbg(rt2x00dev, "IQ AGC %d %d\n", p0, p1); + + + + if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) { + + rt2x00_dbg(rt2x00dev, "IQ AGC IDX 10 %d %d\n", p0_idx10, p1_idx10); +-+ if ((p0_idx10 > 7000*7000) || (p1_idx10 > 7000*7000)) { +-+ if (vga_gain[ch_idx]!=0) +-+ vga_gain[ch_idx] = vga_gain[ch_idx]-1; +++ if ((p0_idx10 > 7000 * 7000) || (p1_idx10 > 7000 * 7000)) { +++ if (vga_gain[ch_idx] != 0) +++ vga_gain[ch_idx] = vga_gain[ch_idx] - 1; + + break; + + } + + } + + +-+ if ((p0 > 2500*2500) || (p1 > 2500*2500)) { +++ if ((p0 > 2500 * 2500) || (p1 > 2500 * 2500)) + + break; +-+ } + + } + + + + if (vga_gain[ch_idx] > 18) + + vga_gain[ch_idx] = 18; +-+ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]); +++ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n", vga_gain[ch_idx], +++ rfvga_gain_table[vga_gain[ch_idx]]); + + + + bbp = (ch_idx == 0) ? 0x29 : 0x47; + + rt2800_bbp_write(rt2x00dev, 158, bbp); +@@ -915,9 +929,8 @@ + + rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, rfb0r39); + + rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42); + + +-+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) { +++ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) + + rt2800_bbp_write(rt2x00dev, 4, bbpr4); +-+ } + + + + rt2800_bbp_write(rt2x00dev, 21, 0x01); + + udelay(1); +@@ -935,16 +948,12 @@ + + rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5); + + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl); + + rt2800_register_write(rt2x00dev, 0x13b8, mac13b8); +-+ +-+ rt2x00_info(rt2x00dev, "TX IQ Calibration Done!\n"); +-+ +-+ return; + +} + + + static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, + bool set_bw, bool is_ht40) + { +-@@ -9672,6 +10609,7 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -9653,6 +10554,7 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rxdcoc_calibration(rt2x00dev); + rt2800_bw_filter_calibration(rt2x00dev, true); + rt2800_bw_filter_calibration(rt2x00dev, false); +@@ -963,11 +972,11 @@ + +#define RF_ALC_NUM 6 + +#define CHAIN_NUM 2 + + +-+typedef struct rf_reg_pair { +++struct rf_reg_pair { + + u8 bank; + + u8 reg; + + u8 value; +-+} rf_reg_pair; +++}; + + /* RT2800 driver data structure */ + struct rt2800_drv_data { +diff --git a/package/kernel/mac80211/patches/rt2x00/011-rt2x00-move-helper-functions-up-in-file.patch b/package/kernel/mac80211/patches/rt2x00/011-rt2x00-move-helper-functions-up-in-file.patch +new file mode 100644 +index 0000000000..07a32b17be +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/011-rt2x00-move-helper-functions-up-in-file.patch +@@ -0,0 +1,94 @@ ++From patchwork Sat Sep 17 20:28:58 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979252 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:28:58 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 11/16] rt2x00: move helper functions up in file ++Message-ID: ++ <c27baa8efd5c29e2bcb2432925d9cdc5c913a125.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Move register access helper functions up to the head of the file so ++they can be used in all functions. ++ ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 40 +++++++++---------- ++ 1 file changed, 20 insertions(+), 20 deletions(-) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -198,6 +198,26 @@ static void rt2800_rfcsr_write_dccal(str ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, reg, value); ++ } ++ +++static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev, +++ const u8 reg, const u8 value) +++{ +++ rt2800_bbp_write(rt2x00dev, 158, reg); +++ rt2800_bbp_write(rt2x00dev, 159, value); +++} +++ +++static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg) +++{ +++ rt2800_bbp_write(rt2x00dev, 158, reg); +++ return rt2800_bbp_read(rt2x00dev, 159); +++} +++ +++static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev, +++ const u8 reg, const u8 value) +++{ +++ rt2800_bbp_write(rt2x00dev, 195, reg); +++ rt2800_bbp_write(rt2x00dev, 196, value); +++} +++ ++ static u8 rt2800_rfcsr_read(struct rt2x00_dev *rt2x00dev, ++ const unsigned int word) ++ { ++@@ -6947,26 +6967,6 @@ static void rt2800_init_bbp_5592(struct ++ rt2800_bbp_write(rt2x00dev, 103, 0xc0); ++ } ++ ++-static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev, ++- const u8 reg, const u8 value) ++-{ ++- rt2800_bbp_write(rt2x00dev, 195, reg); ++- rt2800_bbp_write(rt2x00dev, 196, value); ++-} ++- ++-static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev, ++- const u8 reg, const u8 value) ++-{ ++- rt2800_bbp_write(rt2x00dev, 158, reg); ++- rt2800_bbp_write(rt2x00dev, 159, value); ++-} ++- ++-static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg) ++-{ ++- rt2800_bbp_write(rt2x00dev, 158, reg); ++- return rt2800_bbp_read(rt2x00dev, 159); ++-} ++- ++ static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev) ++ { ++ u8 bbp; +diff --git a/package/kernel/mac80211/patches/rt2x00/012-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/012-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch +new file mode 100644 +index 0000000000..e989205ba2 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/012-rt2x00-fix-HT20-HT40-bandwidth-switch-on-MT7620.patch +@@ -0,0 +1,56 @@ ++From patchwork Sat Sep 17 20:29:13 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979253 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:29:13 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 12/16] rt2x00: fix HT20/HT40 bandwidth switch on MT7620 ++Message-ID: ++ <1664d89ba149f7b0bcec18b2a2abaedf49654507.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Add missing configuration of the channel bandwidth filter to the ++channel setup function for MT7620. ++ ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 8 ++++++++ ++ 1 file changed, 8 insertions(+) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -3855,6 +3855,14 @@ static void rt2800_config_channel_rf7620 ++ rfcsr |= tx_agc_fc; ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr); ++ } +++ +++ if (conf_is_ht40(conf)) { +++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x10); +++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x2f); +++ } else { +++ rt2800_bbp_glrt_write(rt2x00dev, 141, 0x1a); +++ rt2800_bbp_glrt_write(rt2x00dev, 157, 0x40); +++ } ++ } ++ ++ static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev, +diff --git a/package/kernel/mac80211/patches/rt2x00/013-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/013-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT7620.patch +new file mode 100644 +index 0000000000..3d7af17b16 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/013-rt2x00-set-correct-TX_SW_CFG1-MAC-register-for-MT7620.patch +@@ -0,0 +1,52 @@ ++From patchwork Sat Sep 17 20:29:26 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979254 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:29:26 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 13/16] rt2x00: set correct TX_SW_CFG1 MAC register for ++ MT7620 ++Message-ID: ++ <4be38975ce600a34249e12d09a3cb758c6e71071.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Set correct TX_SW_CFG1 MAC register as it is done also in v3 of the ++vendor driver[1]. ++ ++[1]: https://gitlab.com/dm38/padavan-ng/-/blob/master/trunk/proprietary/rt_wifi/rtpci/3.0.X.X/mt76x2/chips/rt6352.c#L531 ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -5966,7 +5966,7 @@ static int rt2800_init_registers(struct ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); ++ } else if (rt2x00_rt(rt2x00dev, RT6352)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); ++- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); +++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); ++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); ++ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); +diff --git a/package/kernel/mac80211/patches/rt2x00/014-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/014-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch +new file mode 100644 +index 0000000000..27b8d92cd2 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/014-rt2x00-set-VGC-gain-for-both-chains-of-MT7620.patch +@@ -0,0 +1,50 @@ ++From patchwork Sat Sep 17 20:29:40 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979255 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:29:40 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 14/16] rt2x00: set VGC gain for both chains of MT7620 ++Message-ID: ++ <29e161397e5c9d9399da0fe87d44458aa2b90a78.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Set bbp66 for all chains of the MT7620. ++ ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- ++ 1 file changed, 2 insertions(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -5743,7 +5743,8 @@ static inline void rt2800_set_vgc(struct ++ if (qual->vgc_level != vgc_level) { ++ if (rt2x00_rt(rt2x00dev, RT3572) || ++ rt2x00_rt(rt2x00dev, RT3593) || ++- rt2x00_rt(rt2x00dev, RT3883)) { +++ rt2x00_rt(rt2x00dev, RT3883) || +++ rt2x00_rt(rt2x00dev, RT6352)) { ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, ++ vgc_level); ++ } else if (rt2x00_rt(rt2x00dev, RT5592)) { +diff --git a/package/kernel/mac80211/patches/rt2x00/015-rt2x00-set-SoC-wmac-clock-register.patch b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-set-SoC-wmac-clock-register.patch +new file mode 100644 +index 0000000000..3cadc91da6 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-set-SoC-wmac-clock-register.patch +@@ -0,0 +1,70 @@ ++From patchwork Sat Sep 17 20:29:55 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979256 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++Date: Sat, 17 Sep 2022 21:29:55 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 15/16] rt2x00: set SoC wmac clock register ++Message-ID: ++ <3e275d259f476f597dab91a9c395015ef3fe3284.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Instead of using the default value 33 (pci), set US_CYC_CNT init based ++on Programming guide: ++If available, set chipset bus clock with fallback to cpu clock/3. ++ ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 21 +++++++++++++++++++ ++ 1 file changed, 21 insertions(+) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -6229,6 +6229,27 @@ static int rt2800_init_registers(struct ++ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); ++ rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125); ++ rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); +++ } else if (rt2x00_is_soc(rt2x00dev)) { +++ struct clk *clk = clk_get_sys("bus", NULL); +++ int rate; +++ +++ if (IS_ERR(clk)) { +++ clk = clk_get_sys("cpu", NULL); +++ +++ if (IS_ERR(clk)) { +++ rate = 125; +++ } else { +++ rate = clk_get_rate(clk) / 3000000; +++ clk_put(clk); +++ } +++ } else { +++ rate = clk_get_rate(clk) / 1000000; +++ clk_put(clk); +++ } +++ +++ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); +++ rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, rate); +++ rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); ++ } ++ ++ reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0); +diff --git a/package/kernel/mac80211/patches/rt2x00/016-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch +new file mode 100644 +index 0000000000..5ddbbf1dd6 +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-correctly-set-BBP-register-86-for-MT7620.patch +@@ -0,0 +1,79 @@ ++From patchwork Sat Sep 17 20:30:09 2022 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> ++X-Patchwork-Id: 12979257 ++X-Patchwork-Delegate: kvalo@adurom.com ++Return-Path: <linux-wireless-owner@kernel.org> ++X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ++ aws-us-west-2-korg-lkml-1.web.codeaurora.org ++Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) ++ by smtp.lore.kernel.org (Postfix) with ESMTP id E9118ECAAA1 ++ for <linux-wireless@archiver.kernel.org>; ++ Sat, 17 Sep 2022 20:30:22 +0000 (UTC) ++Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand ++ id S229639AbiIQUaV (ORCPT ++ <rfc822;linux-wireless@archiver.kernel.org>); ++ Sat, 17 Sep 2022 16:30:21 -0400 ++Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53912 "EHLO ++ lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org ++ with ESMTP id S229628AbiIQUaT (ORCPT ++ <rfc822;linux-wireless@vger.kernel.org>); ++ Sat, 17 Sep 2022 16:30:19 -0400 ++Received: from fudo.makrotopia.org (fudo.makrotopia.org ++ [IPv6:2a07:2ec0:3002::71]) ++ by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1AEA822B27 ++ for <linux-wireless@vger.kernel.org>; ++ Sat, 17 Sep 2022 13:30:16 -0700 (PDT) ++Received: from local ++ by fudo.makrotopia.org with esmtpsa ++ (TLS1.3:TLS_AES_256_GCM_SHA384:256) ++ (Exim 4.96) ++ (envelope-from <daniel@makrotopia.org>) ++ id 1oZeS7-0003ra-0k; ++ Sat, 17 Sep 2022 22:30:15 +0200 ++Date: Sat, 17 Sep 2022 21:30:09 +0100 ++From: Daniel Golle <daniel@makrotopia.org> ++To: linux-wireless@vger.kernel.org, Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ "David S. Miller" <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++Subject: [PATCH v3 16/16] rt2x00: correctly set BBP register 86 for MT7620 ++Message-ID: ++ <257267247ee4fa7ebc6a5d0c4948b3f8119c0d77.1663445157.git.daniel@makrotopia.org> ++References: <cover.1663445157.git.daniel@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++In-Reply-To: <cover.1663445157.git.daniel@makrotopia.org> ++Precedence: bulk ++List-ID: <linux-wireless.vger.kernel.org> ++X-Mailing-List: linux-wireless@vger.kernel.org ++ ++Instead of 0 set the correct value for BBP register 86 for MT7620. ++ ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++Acked-by: Stanislaw Gruszka <stf_xl@wp.pl> ++--- ++ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++- ++ 1 file changed, 4 insertions(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -4225,7 +4225,10 @@ static void rt2800_config_channel(struct ++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); ++- rt2800_bbp_write(rt2x00dev, 86, 0); +++ if (rt2x00_rt(rt2x00dev, RT6352)) +++ rt2800_bbp_write(rt2x00dev, 86, 0x38); +++ else +++ rt2800_bbp_write(rt2x00dev, 86, 0); ++ } ++ ++ if (rf->channel <= 14) { +diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch +index e74d9a9aa0..ba16e85510 100644 +--- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch ++++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch +@@ -1,6 +1,6 @@ + --- a/local-symbols + +++ b/local-symbols +-@@ -332,6 +332,7 @@ RT2X00_LIB_FIRMWARE= ++@@ -345,6 +345,7 @@ RT2X00_LIB_FIRMWARE= + RT2X00_LIB_CRYPTO= + RT2X00_LIB_LEDS= + RT2X00_LIB_DEBUGFS= +@@ -48,7 +48,7 @@ + obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +-@@ -37,6 +37,8 @@ struct rt2800_drv_data { ++@@ -47,6 +47,8 @@ struct rt2800_drv_data { + struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; + }; + +@@ -57,7 +57,7 @@ + struct rt2800_ops { + u32 (*register_read)(struct rt2x00_dev *rt2x00dev, + const unsigned int offset); +-@@ -135,6 +137,15 @@ static inline int rt2800_read_eeprom(str ++@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str + { + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; + +@@ -105,7 +105,7 @@ + .drv_init_registers = rt2800mmio_init_registers, + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-@@ -694,6 +694,7 @@ enum rt2x00_capability_flags { ++@@ -703,6 +703,7 @@ enum rt2x00_capability_flags { + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, + REQUIRE_DELAYED_RFKILL, +@@ -113,7 +113,7 @@ + + /* + * Capabilities +-@@ -970,6 +971,11 @@ struct rt2x00_dev { ++@@ -980,6 +981,11 @@ struct rt2x00_dev { + const struct firmware *fw; + + /* +@@ -127,7 +127,7 @@ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1406,6 +1406,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de ++@@ -1419,6 +1419,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); + INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); + +@@ -138,7 +138,7 @@ + /* + * Let the driver probe the device to detect the capabilities. + */ +-@@ -1549,6 +1553,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ ++@@ -1559,6 +1563,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ + * Free the driver data. + */ + kfree(rt2x00dev->drv_data); +@@ -193,7 +193,7 @@ + + if (pdata && pdata->eeprom_file_name) + + return pdata->eeprom_file_name; + + +-+ return NULL +++ return NULL; + +} + + + +static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) +diff --git a/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch b/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch +index 9dffef1812..431e090237 100644 +--- a/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch ++++ b/package/kernel/mac80211/patches/rt2x00/603-rt2x00-of_load_eeprom_filename.patch +@@ -8,7 +8,7 @@ + + #include "rt2x00.h" + #include "rt2x00lib.h" +-@@ -34,11 +35,21 @@ static const char * ++@@ -34,10 +35,20 @@ static const char * + rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) + { + struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; +@@ -20,14 +20,12 @@ + if (pdata && pdata->eeprom_file_name) + return pdata->eeprom_file_name; + +-- return NULL + +#ifdef CONFIG_OF + + np = rt2x00dev->dev->of_node; + + if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0) + + return eep; + +#endif + + +-+ return NULL; ++ return NULL; + } + +- static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) +diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch +index 6a8e594d5e..ffee2189d2 100644 +--- a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch ++++ b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch +@@ -12,7 +12,7 @@ + #endif /* _RT2X00_PLATFORM_H */ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1012,6 +1012,22 @@ static int rt2x00lib_probe_hw_modes(stru ++@@ -1007,6 +1007,22 @@ static int rt2x00lib_probe_hw_modes(stru + unsigned int num_rates; + unsigned int i; + +@@ -37,7 +37,7 @@ + num_rates += 4; + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-@@ -399,6 +399,7 @@ struct hw_mode_spec { ++@@ -408,6 +408,7 @@ struct hw_mode_spec { + unsigned int supported_bands; + #define SUPPORT_BAND_2GHZ 0x00000001 + #define SUPPORT_BAND_5GHZ 0x00000002 +diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch +index b5b2c61037..37553bb80a 100644 +--- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch ++++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch +@@ -1,19 +1,18 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80 ++@@ -989,6 +989,12 @@ static void rt2x00lib_rate(struct ieee80 + + void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) + { + + struct rt2x00_platform_data *pdata; +- const char *mac_addr; +- +++ + + pdata = rt2x00dev->dev->platform_data; + + if (pdata && pdata->mac_address) + + ether_addr_copy(eeprom_mac_addr, pdata->mac_address); + + +- mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); +- if (!IS_ERR(mac_addr)) +- ether_addr_copy(eeprom_mac_addr, mac_addr); ++ of_get_mac_address(rt2x00dev->dev->of_node, eeprom_mac_addr); ++ ++ if (!is_valid_ether_addr(eeprom_mac_addr)) { + --- a/include/linux/rt2x00_platform.h + +++ b/include/linux/rt2x00_platform.h + @@ -14,6 +14,7 @@ +diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch +index ff8b2c947b..6211809c0a 100644 +--- a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch ++++ b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1016,6 +1016,16 @@ static int rt2x00lib_probe_hw_modes(stru ++@@ -1012,6 +1012,16 @@ static int rt2x00lib_probe_hw_modes(stru + struct ieee80211_rate *rates; + unsigned int num_rates; + unsigned int i; +diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch +index 039c6f6afc..acc8a8edb8 100644 +--- a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch ++++ b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch +@@ -8,7 +8,7 @@ + + #include "rt2x00.h" + #include "rt2800lib.h" +-@@ -9530,6 +9531,17 @@ static int rt2800_init_eeprom(struct rt2 ++@@ -11131,6 +11132,17 @@ static int rt2800_init_eeprom(struct rt2 + rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); + rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); + +diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch +index 88d6dd559b..5ef5fc8def 100644 +--- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch ++++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1344,7 +1344,7 @@ static inline void rt2x00lib_set_if_comb ++@@ -1358,7 +1358,7 @@ static inline void rt2x00lib_set_if_comb + */ + if_limit = &rt2x00dev->if_limits_ap; + if_limit->max = rt2x00dev->ops->max_ap_intf; +diff --git a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch b/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch +deleted file mode 100644 +index fca1fb2cd4..0000000000 +--- a/package/kernel/mac80211/patches/rt2x00/612-rt2x00-led-tpt-trigger-support.patch ++++ /dev/null +@@ -1,44 +0,0 @@ +-From: David Bauer <mail@david-bauer.net> +-Date: Mon, 16 Dec 2019 20:47:06 +0100 +-Subject: [PATCH] rt2x00: add throughput LED trigger +- +-This adds a (currently missing) throughput LED trigger for the rt2x00 +-driver. Previously, LED triggers had to be assigned to the netdev, which +-was limited to a single VAP. +- +-Signed-off-by: David Bauer <mail@david-bauer.net> +-Tested-by: Christoph Krapp <achterin@googlemail.com> +- +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1129,6 +1129,19 @@ static void rt2x00lib_remove_hw(struct r +- kfree(rt2x00dev->spec.channels_info); +- } +- +-+static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = { +-+ { .throughput = 0 * 1024, .blink_time = 334 }, +-+ { .throughput = 1 * 1024, .blink_time = 260 }, +-+ { .throughput = 2 * 1024, .blink_time = 220 }, +-+ { .throughput = 5 * 1024, .blink_time = 190 }, +-+ { .throughput = 10 * 1024, .blink_time = 170 }, +-+ { .throughput = 25 * 1024, .blink_time = 150 }, +-+ { .throughput = 54 * 1024, .blink_time = 130 }, +-+ { .throughput = 120 * 1024, .blink_time = 110 }, +-+ { .throughput = 265 * 1024, .blink_time = 80 }, +-+ { .throughput = 586 * 1024, .blink_time = 50 }, +-+}; +-+ +- static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) +- { +- struct hw_mode_spec *spec = &rt2x00dev->spec; +-@@ -1210,6 +1223,10 @@ static int rt2x00lib_probe_hw(struct rt2 +- +- #undef RT2X00_TASKLET_INIT +- +-+ ieee80211_create_tpt_led_trigger(rt2x00dev->hw, +-+ IEEE80211_TPT_LEDTRIG_FL_RADIO, rt2x00_tpt_blink, +-+ ARRAY_SIZE(rt2x00_tpt_blink)); +-+ +- /* +- * Register HW. +- */ +diff --git a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch b/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch +deleted file mode 100644 +index 31a7baeee7..0000000000 +--- a/package/kernel/mac80211/patches/rt2x00/992-rt2x00-save-survey-for-every-channel-visited.patch ++++ /dev/null +@@ -1,183 +0,0 @@ +---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -1238,6 +1238,8 @@ void rt2800_watchdog(struct rt2x00_dev * +- if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) +- return; +- +-+ rt2800_update_survey(rt2x00dev); +-+ +- queue_for_each(rt2x00dev, queue) { +- switch (queue->qid) { +- case QID_AC_VO: +-@@ -1274,6 +1276,18 @@ void rt2800_watchdog(struct rt2x00_dev * +- } +- EXPORT_SYMBOL_GPL(rt2800_watchdog); +- +-+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev) +-+{ +-+ struct ieee80211_channel *chan = rt2x00dev->hw->conf.chandef.chan; +-+ struct rt2x00_chan_survey *chan_survey = +-+ &rt2x00dev->chan_survey[chan->hw_value]; +-+ +-+ chan_survey->time_idle += rt2800_register_read(rt2x00dev, CH_IDLE_STA); +-+ chan_survey->time_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA); +-+ chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); +-+} +-+EXPORT_SYMBOL_GPL(rt2800_update_survey); +-+ +- static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, +- unsigned int index) +- { +-@@ -12199,26 +12213,30 @@ int rt2800_get_survey(struct ieee80211_h +- { +- struct rt2x00_dev *rt2x00dev = hw->priv; +- struct ieee80211_conf *conf = &hw->conf; +-- u32 idle, busy, busy_ext; +-+ struct rt2x00_chan_survey *chan_survey = +-+ &rt2x00dev->chan_survey[idx]; +-+ enum nl80211_band band = NL80211_BAND_2GHZ; +- +-- if (idx != 0) +-+ if (idx >= rt2x00dev->bands[band].n_channels) { +-+ idx -= rt2x00dev->bands[band].n_channels; +-+ band = NL80211_BAND_5GHZ; +-+ } +-+ +-+ if (idx >= rt2x00dev->bands[band].n_channels) +- return -ENOENT; +- +-- survey->channel = conf->chandef.chan; +-+ if (idx == 0) +-+ rt2800_update_survey(rt2x00dev); +- +-- idle = rt2800_register_read(rt2x00dev, CH_IDLE_STA); +-- busy = rt2800_register_read(rt2x00dev, CH_BUSY_STA); +-- busy_ext = rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC); +-- +-- if (idle || busy) { +-- survey->filled = SURVEY_INFO_TIME | +-- SURVEY_INFO_TIME_BUSY | +-- SURVEY_INFO_TIME_EXT_BUSY; +-- +-- survey->time = (idle + busy) / 1000; +-- survey->time_busy = busy / 1000; +-- survey->time_ext_busy = busy_ext / 1000; +-- } +-+ survey->channel = &rt2x00dev->bands[band].channels[idx]; +-+ +-+ survey->filled = SURVEY_INFO_TIME | +-+ SURVEY_INFO_TIME_BUSY | +-+ SURVEY_INFO_TIME_EXT_BUSY; +-+ +-+ survey->time = div_u64(chan_survey->time_idle + chan_survey->time_busy, 1000); +-+ survey->time_busy = div_u64(chan_survey->time_busy, 1000); +-+ survey->time_ext_busy = div_u64(chan_survey->time_ext_busy, 1000); +- +- if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) +- survey->filled |= SURVEY_INFO_IN_USE; +---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +-@@ -243,6 +243,7 @@ bool rt2800_txstatus_timeout(struct rt2x +- bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev); +- +- void rt2800_watchdog(struct rt2x00_dev *rt2x00dev); +-+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev); +- +- void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); +- void rt2800_clear_beacon(struct queue_entry *entry); +---- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +-@@ -360,6 +360,7 @@ static const struct rt2x00lib_ops rt2800 +- .gain_calibration = rt2800_gain_calibration, +- .vco_calibration = rt2800_vco_calibration, +- .watchdog = rt2800_watchdog, +-+ .update_survey = rt2800_update_survey, +- .start_queue = rt2800mmio_start_queue, +- .kick_queue = rt2800mmio_kick_queue, +- .stop_queue = rt2800mmio_stop_queue, +---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +-@@ -214,6 +214,7 @@ static const struct rt2x00lib_ops rt2800 +- .gain_calibration = rt2800_gain_calibration, +- .vco_calibration = rt2800_vco_calibration, +- .watchdog = rt2800_watchdog, +-+ .update_survey = rt2800_update_survey, +- .start_queue = rt2800mmio_start_queue, +- .kick_queue = rt2800mmio_kick_queue, +- .stop_queue = rt2800mmio_stop_queue, +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +-@@ -183,6 +183,15 @@ struct rf_channel { +- }; +- +- /* +-+ * Information structure for channel survey. +-+ */ +-+struct rt2x00_chan_survey { +-+ u64 time_idle; +-+ u64 time_busy; +-+ u64 time_ext_busy; +-+}; +-+ +-+/* +- * Channel information structure +- */ +- struct channel_info { +-@@ -567,6 +576,7 @@ struct rt2x00lib_ops { +- * Data queue handlers. +- */ +- void (*watchdog) (struct rt2x00_dev *rt2x00dev); +-+ void (*update_survey) (struct rt2x00_dev *rt2x00dev); +- void (*start_queue) (struct data_queue *queue); +- void (*kick_queue) (struct data_queue *queue); +- void (*stop_queue) (struct data_queue *queue); +-@@ -755,6 +765,7 @@ struct rt2x00_dev { +- */ +- struct ieee80211_hw *hw; +- struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; +-+ struct rt2x00_chan_survey *chan_survey; +- enum nl80211_band curr_band; +- int curr_freq; +- +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +-@@ -1057,6 +1057,12 @@ static int rt2x00lib_probe_hw_modes(stru +- if (!rates) +- goto exit_free_channels; +- +-+ rt2x00dev->chan_survey = +-+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey), +-+ GFP_KERNEL); +-+ if (!rt2x00dev->chan_survey) +-+ goto exit_free_rates; +-+ +- /* +- * Initialize Rate list. +- */ +-@@ -1108,6 +1114,8 @@ static int rt2x00lib_probe_hw_modes(stru +- +- return 0; +- +-+ exit_free_rates: +-+ kfree(rates); +- exit_free_channels: +- kfree(channels); +- rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n"); +---- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +-@@ -317,6 +317,15 @@ int rt2x00mac_config(struct ieee80211_hw +- return 0; +- +- /* +-+ * To provide correct survey data for survey-based ACS algorithm +-+ * we have to save survey data for current channel before switching. +-+ */ +-+ if (rt2x00dev->ops->lib->update_survey && +-+ (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { +-+ rt2x00dev->ops->lib->update_survey(rt2x00dev); +-+ } +-+ +-+ /* +- * Some configuration parameters (e.g. channel and antenna values) can +- * only be set when the radio is enabled, but do require the RX to +- * be off. During this period we should keep link tuning enabled, +diff --git a/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch +new file mode 100644 +index 0000000000..deaa03be6c +--- /dev/null ++++ b/package/kernel/mac80211/patches/rt2x00/994-rt2x00-import-support-for-external-LNA-on-MT7620.patch +@@ -0,0 +1,161 @@ ++From 0fce1109f894ec7fcd72cb098843a1eff786716a Mon Sep 17 00:00:00 2001 ++From: Daniel Golle <daniel@makrotopia.org> ++Date: Fri, 16 Sep 2022 20:49:42 +0100 ++Subject: [PATCH 16/16] rt2x00: import support for external LNA on MT7620 ++To: linux-wireless@vger.kernel.org, ++ Stanislaw Gruszka <stf_xl@wp.pl>, ++ Helmut Schaa <helmut.schaa@googlemail.com> ++Cc: Kalle Valo <kvalo@kernel.org>, ++ David S. Miller <davem@davemloft.net>, ++ Eric Dumazet <edumazet@google.com>, ++ Jakub Kicinski <kuba@kernel.org>, ++ Paolo Abeni <pabeni@redhat.com>, ++ Johannes Berg <johannes.berg@intel.com> ++ ++In order to carry out calibration on boards with ePA or eLNA the PA pin ++needs to be switch to GPIO mode on MT7620. Implement that by selecting ++pinctrl state "pa_gpio" which should be defined for MT7620 boards with ++eLNA or ePA beside the "default" state. ++ ++Reported-by: Serge Vasilugin <vasilugin@yandex.ru> ++Signed-off-by: Daniel Golle <daniel@makrotopia.org> ++--- ++ .../net/wireless/ralink/rt2x00/rt2800lib.c | 58 +++++++++++++++++++ ++ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 5 ++ ++ .../net/wireless/ralink/rt2x00/rt2x00soc.c | 15 +++++ ++ 3 files changed, 78 insertions(+) ++ ++--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++@@ -304,6 +304,24 @@ static void rt2800_rf_write(struct rt2x0 ++ mutex_unlock(&rt2x00dev->csr_mutex); ++ } ++ +++void rt6352_enable_pa_pin(struct rt2x00_dev *rt2x00dev, int enable) +++{ +++ if (!rt2x00dev->pinctrl) +++ return; +++ +++ if (enable) { +++ if (!rt2x00dev->pins_default) +++ return; +++ +++ pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_default); +++ } else { +++ if (!rt2x00dev->pins_pa_gpio) +++ return; +++ +++ pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_pa_gpio); +++ } +++} +++ ++ static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = { ++ [EEPROM_CHIP_ID] = 0x0000, ++ [EEPROM_VERSION] = 0x0001, ++@@ -4469,6 +4487,29 @@ static void rt2800_config_channel(struct ++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, ++ 0x6C6C6B6C); ++ } +++ +++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { +++ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); +++ reg |= 0x00000101; +++ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); +++ +++ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); +++ reg |= 0x00000101; +++ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); +++ +++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); +++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); +++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); +++ rt2800_bbp_write(rt2x00dev, 75, 0x68); +++ rt2800_bbp_write(rt2x00dev, 76, 0x4C); +++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); +++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); +++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); +++ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in +++ * config channel function in dependence of channel and +++ * HT20/HT40 so don't touch it +++ */ +++ } ++ } ++ ++ bbp = rt2800_bbp_read(rt2x00dev, 4); ++@@ -10583,6 +10624,7 @@ static void rt2800_init_rfcsr_6352(struc ++ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); ++ +++ rt6352_enable_pa_pin(rt2x00dev, 0); ++ rt2800_r_calibration(rt2x00dev); ++ rt2800_rf_self_txdc_cal(rt2x00dev); ++ rt2800_rxdcoc_calibration(rt2x00dev); ++@@ -10590,6 +10632,22 @@ static void rt2800_init_rfcsr_6352(struc ++ rt2800_bw_filter_calibration(rt2x00dev, false); ++ rt2800_loft_iq_calibration(rt2x00dev); ++ rt2800_rxiq_calibration(rt2x00dev); +++ rt6352_enable_pa_pin(rt2x00dev, 1); +++ +++ if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { +++ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66); +++ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20); +++ rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42); +++ rt2800_bbp_write(rt2x00dev, 75, 0x68); +++ rt2800_bbp_write(rt2x00dev, 76, 0x4C); +++ rt2800_bbp_write(rt2x00dev, 79, 0x1C); +++ rt2800_bbp_write(rt2x00dev, 80, 0x0C); +++ rt2800_bbp_write(rt2x00dev, 82, 0xB6); +++ /* bank 0 RF reg 42 and glrt BBP reg 141 will be set in config +++ * channel function in dependence of channel and HT20/HT40, +++ * so don't touch them here. +++ */ +++ } ++ } ++ ++ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) ++--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++@@ -28,6 +28,7 @@ ++ #include <linux/average.h> ++ #include <linux/usb.h> ++ #include <linux/clk.h> +++#include <linux/pinctrl/consumer.h> ++ #include <linux/rt2x00_platform.h> ++ ++ #include <net/mac80211.h> ++@@ -1029,6 +1030,11 @@ struct rt2x00_dev { ++ ++ /* Clock for System On Chip devices. */ ++ struct clk *clk; +++ +++ /* pinctrl and states for System On Chip devices with PA/LNA. */ +++ struct pinctrl *pinctrl; +++ struct pinctrl_state *pins_default; +++ struct pinctrl_state *pins_pa_gpio; ++ }; ++ ++ struct rt2x00_bar_list_entry { ++--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c +++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c ++@@ -97,6 +97,21 @@ int rt2x00soc_probe(struct platform_devi ++ if (retval) ++ goto exit_free_reg; ++ +++ rt2x00dev->pinctrl = devm_pinctrl_get(&pdev->dev); +++ if (IS_ERR(rt2x00dev->pinctrl)) { +++ rt2x00dev->pinctrl = NULL; +++ rt2x00dev->pins_default = NULL; +++ rt2x00dev->pins_pa_gpio = NULL; +++ } else { +++ rt2x00dev->pins_default = pinctrl_lookup_state(rt2x00dev->pinctrl, "default"); +++ if (IS_ERR(rt2x00dev->pins_default)) +++ rt2x00dev->pins_default = NULL; +++ +++ rt2x00dev->pins_pa_gpio = pinctrl_lookup_state(rt2x00dev->pinctrl, "pa_gpio"); +++ if (IS_ERR(rt2x00dev->pins_pa_gpio)) +++ rt2x00dev->pins_pa_gpio = NULL; +++ } +++ ++ return 0; ++ ++ exit_free_reg: +diff --git a/package/kernel/mac80211/patches/rt2x00/990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch b/package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch +similarity index 100% +rename from package/kernel/mac80211/patches/rt2x00/990-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch +rename to package/kernel/mac80211/patches/rt2x00/995-rt2x00-mt7620-introduce-accessors-for-CHIP_VER-register.patch +diff --git a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +similarity index 95% +rename from package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +rename to package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +index 3de00b2267..dab6e05ffd 100644 +--- a/package/kernel/mac80211/patches/rt2x00/991-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch ++++ b/package/kernel/mac80211/patches/rt2x00/996-rt2x00-mt7620-differentiate-based-on-SoC-CHIP_VER.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +-@@ -1042,6 +1042,11 @@ ++@@ -1044,6 +1044,11 @@ + #define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010) + #define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020) + +@@ -14,7 +14,7 @@ + */ + --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c + +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +-@@ -3685,14 +3685,16 @@ static void rt2800_config_channel_rf7620 ++@@ -3778,14 +3778,16 @@ static void rt2800_config_channel_rf7620 + rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4); + rt2800_rfcsr_write(rt2x00dev, 19, rfcsr); + +@@ -39,7 +39,7 @@ + + rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620, +-@@ -3726,18 +3728,23 @@ static void rt2800_config_channel_rf7620 ++@@ -3819,18 +3821,23 @@ static void rt2800_config_channel_rf7620 + rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20); + } + +@@ -73,9 +73,9 @@ + + if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) { + if (conf_is_ht40(conf)) { +-@@ -3837,25 +3844,29 @@ static void rt2800_config_alc(struct rt2 +- if (i == 10000) +- rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n"); ++@@ -3929,25 +3936,29 @@ static void rt2800_config_alc(struct rt2 ++ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev, MAC_STATUS_CFG_BBP_RF_BUSY))) ++ rt2x00_warn(rt2x00dev, "RF busy while configuring ALC\n"); + + - if (chan->center_freq > 2457) { + - bbp = rt2800_bbp_read(rt2x00dev, 30); +@@ -121,12 +121,12 @@ + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl); + + rt2800_vco_calibration(rt2x00dev); +-@@ -5887,18 +5898,33 @@ static int rt2800_init_registers(struct ++@@ -6011,18 +6022,33 @@ static int rt2800_init_registers(struct + } else if (rt2x00_rt(rt2x00dev, RT5350)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); + } else if (rt2x00_rt(rt2x00dev, RT6352)) { + - rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); +-- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); ++- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); + - rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + - rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); + - rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); +@@ -150,7 +150,7 @@ + + 0x00550055); + + } else { + + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); +-+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); +++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); + + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + + rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); + + rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); +@@ -167,7 +167,7 @@ + reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1); + rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0); + rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg); +-@@ -7042,14 +7068,16 @@ static void rt2800_init_bbp_6352(struct ++@@ -7127,14 +7153,16 @@ static void rt2800_init_bbp_6352(struct + rt2800_bbp_write(rt2x00dev, 188, 0x00); + rt2800_bbp_write(rt2x00dev, 189, 0x00); + +@@ -192,7 +192,7 @@ + + /* BBP for G band GLRT function (BBP_128 ~ BBP_221) */ + rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00); +-@@ -10388,31 +10416,36 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -10408,31 +10436,36 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write(rt2x00dev, 42, 0x5B); + rt2800_rfcsr_write(rt2x00dev, 43, 0x00); + +@@ -254,7 +254,7 @@ + + /* Initialize RF channel register to default value */ + rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03); +-@@ -10478,63 +10511,71 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -10498,63 +10531,71 @@ static void rt2800_init_rfcsr_6352(struc + + rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5); + +@@ -383,7 +383,7 @@ + + /* Initialize RF DC calibration register to default value */ + rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47); +-@@ -10597,12 +10638,17 @@ static void rt2800_init_rfcsr_6352(struc ++@@ -10617,12 +10658,17 @@ static void rt2800_init_rfcsr_6352(struc + rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00); + +@@ -404,5 +404,5 @@ + + rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); + + } + ++ rt6352_enable_pa_pin(rt2x00dev, 0); + rt2800_r_calibration(rt2x00dev); +- rt2800_rf_self_txdc_cal(rt2x00dev); diff --git a/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch b/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch deleted file mode 100644 index 3daf65e967..0000000000 @@ -5292,7 +9323,7 @@ diff --git a/package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_ similarity index 97% rename from package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch rename to package/kernel/mac80211/patches/subsys/303-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch -index f58d2eb4cb..777c93cb90 100644 +index f58d2eb4cb..1ceb2be25c 100644 --- a/package/kernel/mac80211/patches/subsys/306-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch +++ b/package/kernel/mac80211/patches/subsys/303-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch @@ -52,7 +52,7 @@ Signed-off-by: Xing Song <xing.song@mediatek.com> @@ -5300,7 +9331,7 @@ index f58d2eb4cb..777c93cb90 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -2941,6 +2941,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -+@@ -2949,6 +2949,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 ++@@ -2948,6 +2948,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 if (!fwd_skb) goto out; @@ -5358,7 +9389,7 @@ index 1c940d3db2..c43cd3acb9 100644 diff --git a/package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch b/package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch new file mode 100644 -index 0000000000..c534d1570a +index 0000000000..fba0912e80 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch @@ -0,0 +1,74 @@ @@ -5375,7 +9406,7 @@ index 0000000000..c534d1570a + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c -+@@ -3001,15 +3001,19 @@ static void mac80211_hwsim_he_capab(stru ++@@ -3004,15 +3004,19 @@ static void mac80211_hwsim_he_capab(stru + { + u16 n_iftype_data; + @@ -5398,7 +9429,7 @@ index 0000000000..c534d1570a + return; + } + -+@@ -3299,6 +3303,12 @@ static int mac80211_hwsim_new_radio(stru ++@@ -3302,6 +3306,12 @@ static int mac80211_hwsim_new_radio(stru + sband->vht_cap.vht_mcs.tx_mcs_map = + sband->vht_cap.vht_mcs.rx_mcs_map; + break; @@ -5411,7 +9442,7 @@ index 0000000000..c534d1570a + case NL80211_BAND_S1GHZ: + memcpy(&sband->s1g_cap, &hwsim_s1g_cap, + sizeof(sband->s1g_cap)); -+@@ -3309,6 +3319,13 @@ static int mac80211_hwsim_new_radio(stru ++@@ -3312,6 +3322,13 @@ static int mac80211_hwsim_new_radio(stru + continue; + } + @@ -5425,7 +9456,7 @@ index 0000000000..c534d1570a + sband->ht_cap.ht_supported = true; + sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | -+@@ -3322,10 +3339,6 @@ static int mac80211_hwsim_new_radio(stru ++@@ -3325,10 +3342,6 @@ static int mac80211_hwsim_new_radio(stru + sband->ht_cap.mcs.rx_mask[0] = 0xff; + sband->ht_cap.mcs.rx_mask[1] = 0xff; + sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; @@ -5438,7 +9469,7 @@ index 0000000000..c534d1570a + /* By default all radios belong to the first group */ diff --git a/package/kernel/mac80211/patches/subsys/308-mac80211-add-support-for-.ndo_fill_forward_path.patch b/package/kernel/mac80211/patches/subsys/308-mac80211-add-support-for-.ndo_fill_forward_path.patch new file mode 100644 -index 0000000000..272d84f35e +index 0000000000..4b9d874cfe --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/308-mac80211-add-support-for-.ndo_fill_forward_path.patch @@ -0,0 +1,178 @@ @@ -5513,7 +9544,7 @@ index 0000000000..272d84f35e + #endif /* __MAC80211_DRIVER_OPS */ +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h -+@@ -1485,7 +1485,7 @@ struct ieee80211_local { ++@@ -1490,7 +1490,7 @@ struct ieee80211_local { + }; + + static inline struct ieee80211_sub_if_data * @@ -5625,9 +9656,21 @@ similarity index 100% rename from package/kernel/mac80211/patches/subsys/353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch rename to package/kernel/mac80211/patches/subsys/309-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch diff --git a/package/kernel/mac80211/patches/subsys/354-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch -similarity index 100% +similarity index 94% rename from package/kernel/mac80211/patches/subsys/354-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch rename to package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch +index 16bcbc2ef9..3be43b8782 100644 +--- a/package/kernel/mac80211/patches/subsys/354-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch ++++ b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch +@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> + + --- a/net/mac80211/rc80211_minstrel_ht.c + +++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -700,7 +700,8 @@ minstrel_ht_calc_rate_stats(struct minst ++@@ -703,7 +703,8 @@ minstrel_ht_calc_rate_stats(struct minst + unsigned int cur_prob; + + if (unlikely(mrs->attempts > 0)) { diff --git a/package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch b/package/kernel/mac80211/patches/subsys/310-net-fq_impl-bulk-free-packets-from-a-flow-on-overmem.patch deleted file mode 100644 index 05a888006e..0000000000 @@ -5730,18 +9773,45 @@ index 05a888006e..0000000000 - fq->overlimit++; - if (oom) { diff --git a/package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch -similarity index 93% +similarity index 90% rename from package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch rename to package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch -index aec2e07781..a6817bd4a6 100644 +index aec2e07781..13bed48ec6 100644 --- a/package/kernel/mac80211/patches/subsys/355-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch +++ b/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch +@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> + + --- a/net/mac80211/rc80211_minstrel_ht.c + +++ b/net/mac80211/rc80211_minstrel_ht.c +-@@ -511,6 +511,14 @@ minstrel_ht_set_best_prob_rate(struct mi ++@@ -514,6 +514,14 @@ minstrel_ht_set_best_prob_rate(struct mi + int cur_tp_avg, cur_group, cur_idx; + int max_gpr_group, max_gpr_idx; + int max_gpr_tp_avg, max_gpr_prob; +@@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> + + cur_group = MI_RATE_GROUP(index); + cur_idx = MI_RATE_IDX(index); +-@@ -532,11 +540,6 @@ minstrel_ht_set_best_prob_rate(struct mi ++@@ -535,11 +543,6 @@ minstrel_ht_set_best_prob_rate(struct mi + !minstrel_ht_is_legacy_group(max_tp_group)) + return; + +@@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> + max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); + max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); + max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; +-@@ -594,40 +597,6 @@ minstrel_ht_assign_best_tp_rates(struct ++@@ -597,40 +600,6 @@ minstrel_ht_assign_best_tp_rates(struct + + } + @@ -86,7 +86,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> static u16 __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, enum minstrel_sample_type type) -@@ -1111,8 +1080,6 @@ minstrel_ht_update_stats(struct minstrel -+@@ -1107,8 +1076,6 @@ minstrel_ht_update_stats(struct minstrel ++@@ -1110,8 +1079,6 @@ minstrel_ht_update_stats(struct minstrel mi->max_prob_rate = tmp_max_prob_rate; @@ -5750,7 +9820,7 @@ index aec2e07781..a6817bd4a6 100644 #ifdef CPTCFG_MAC80211_DEBUGFS -@@ -1157,7 +1124,7 @@ minstrel_ht_txstat_valid(struct minstrel -+@@ -1153,7 +1120,7 @@ minstrel_ht_txstat_valid(struct minstrel ++@@ -1156,7 +1123,7 @@ minstrel_ht_txstat_valid(struct minstrel } static void @@ -5759,7 +9829,7 @@ index aec2e07781..a6817bd4a6 100644 int group, orig_group; -@@ -1172,11 +1139,7 @@ minstrel_downgrade_rate(struct minstrel_ -+@@ -1168,11 +1135,7 @@ minstrel_downgrade_rate(struct minstrel_ ++@@ -1171,11 +1138,7 @@ minstrel_downgrade_rate(struct minstrel_ minstrel_mcs_groups[orig_group].streams) continue; @@ -5768,7 +9838,7 @@ index aec2e07781..a6817bd4a6 100644 } -@@ -1210,7 +1173,7 @@ minstrel_ht_tx_status(void *priv, struct -+@@ -1183,7 +1146,7 @@ minstrel_ht_tx_status(void *priv, struct ++@@ -1186,7 +1149,7 @@ minstrel_ht_tx_status(void *priv, struct struct ieee80211_tx_info *info = st->info; struct minstrel_ht_sta *mi = priv_sta; struct ieee80211_tx_rate *ar = info->status.rates; @@ -5777,7 +9847,7 @@ index aec2e07781..a6817bd4a6 100644 u32 update_interval = mp->update_interval; bool last, update = false; -@@ -1256,18 +1219,13 @@ minstrel_ht_tx_status(void *priv, struct -+@@ -1233,18 +1196,13 @@ minstrel_ht_tx_status(void *priv, struct ++@@ -1236,18 +1199,13 @@ minstrel_ht_tx_status(void *priv, struct /* * check for sudden death of spatial multiplexing, * downgrade to a lower number of streams if necessary. @@ -6524,7 +10594,7 @@ index 1d7bbee400..0000000000 - spin_unlock_bh(&fq->lock); diff --git a/package/kernel/mac80211/patches/subsys/313-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/313-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch new file mode 100644 -index 0000000000..4fc8b592c2 +index 0000000000..429886d701 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/313-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch @@ -0,0 +1,493 @@ @@ -6768,7 +10838,7 @@ index 0000000000..4fc8b592c2 + static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD }, + [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, -+@@ -783,6 +793,9 @@ static const struct nla_policy nl80211_p ++@@ -788,6 +798,9 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 }, + [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 }, + [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy), @@ -6778,7 +10848,7 @@ index 0000000000..4fc8b592c2 + }; + + /* policy for the key attributes */ -+@@ -2231,6 +2244,35 @@ fail: ++@@ -2236,6 +2249,35 @@ fail: + return -ENOBUFS; + } + @@ -6814,7 +10884,7 @@ index 0000000000..4fc8b592c2 + struct nl80211_dump_wiphy_state { + s64 filter_wiphy; + long start; -+@@ -2816,6 +2858,9 @@ static int nl80211_send_wiphy(struct cfg ++@@ -2821,6 +2863,9 @@ static int nl80211_send_wiphy(struct cfg + if (nl80211_put_sar_specs(rdev, msg)) + goto nla_put_failure; + @@ -6824,7 +10894,7 @@ index 0000000000..4fc8b592c2 + /* done */ + state->split_start = 0; + break; -+@@ -5005,6 +5050,96 @@ static int validate_beacon_tx_rate(struc ++@@ -5020,6 +5065,96 @@ static int validate_beacon_tx_rate(struc + return 0; + } + @@ -6921,7 +10991,7 @@ index 0000000000..4fc8b592c2 + static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev, + struct nlattr *attrs[], + struct cfg80211_beacon_data *bcn) -+@@ -5085,6 +5220,17 @@ static int nl80211_parse_beacon(struct c ++@@ -5100,6 +5235,17 @@ static int nl80211_parse_beacon(struct c + bcn->ftm_responder = -1; + } + @@ -6939,7 +11009,7 @@ index 0000000000..4fc8b592c2 + return 0; + } + -+@@ -5541,6 +5687,17 @@ static int nl80211_start_ap(struct sk_bu ++@@ -5556,6 +5702,17 @@ static int nl80211_start_ap(struct sk_bu + goto out; + } + @@ -6957,7 +11027,7 @@ index 0000000000..4fc8b592c2 + nl80211_calculate_ap_params(¶ms); + + if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT]) -+@@ -5562,6 +5719,11 @@ static int nl80211_start_ap(struct sk_bu ++@@ -5577,6 +5734,11 @@ static int nl80211_start_ap(struct sk_bu + + out: + kfree(params.acl); @@ -6969,7 +11039,7 @@ index 0000000000..4fc8b592c2 + + return err; + } -+@@ -5586,12 +5748,14 @@ static int nl80211_set_beacon(struct sk_ ++@@ -5601,12 +5763,14 @@ static int nl80211_set_beacon(struct sk_ + + err = nl80211_parse_beacon(rdev, info->attrs, ¶ms); + if (err) @@ -6985,7 +11055,7 @@ index 0000000000..4fc8b592c2 + return err; + } + -+@@ -9268,12 +9432,14 @@ static int nl80211_channel_switch(struct ++@@ -9283,12 +9447,14 @@ static int nl80211_channel_switch(struct + + err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_after); + if (err) @@ -7003,7 +11073,7 @@ index 0000000000..4fc8b592c2 + + err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX, + info->attrs[NL80211_ATTR_CSA_IES], -+@@ -9392,6 +9558,8 @@ skip_beacons: ++@@ -9407,6 +9573,8 @@ skip_beacons: + wdev_unlock(wdev); + + free: @@ -7012,7 +11082,7 @@ index 0000000000..4fc8b592c2 + kfree(csa_attrs); + return err; + } -+@@ -14939,6 +15107,8 @@ static int nl80211_color_change(struct s ++@@ -14959,6 +15127,8 @@ static int nl80211_color_change(struct s + wdev_unlock(wdev); + + out: @@ -7023,7 +11093,7 @@ index 0000000000..4fc8b592c2 + } diff --git a/package/kernel/mac80211/patches/subsys/314-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch b/package/kernel/mac80211/patches/subsys/314-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch new file mode 100644 -index 0000000000..90c56b4e43 +index 0000000000..2038ee69db --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/314-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch @@ -0,0 +1,378 @@ @@ -7315,7 +11385,7 @@ index 0000000000..90c56b4e43 ++} +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c -+@@ -796,6 +796,7 @@ static const struct nla_policy nl80211_p ++@@ -801,6 +801,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MBSSID_CONFIG] = + NLA_POLICY_NESTED(nl80211_mbssid_config_policy), + [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, @@ -7323,7 +11393,7 @@ index 0000000000..90c56b4e43 + }; + + /* policy for the key attributes */ -+@@ -9272,12 +9273,6 @@ static int nl80211_start_radar_detection ++@@ -9287,12 +9288,6 @@ static int nl80211_start_radar_detection + if (err) + return err; + @@ -7336,7 +11406,7 @@ index 0000000000..90c56b4e43 + err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); + if (err < 0) + return err; -+@@ -9288,6 +9283,16 @@ static int nl80211_start_radar_detection ++@@ -9303,6 +9298,16 @@ static int nl80211_start_radar_detection + if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) + return -EINVAL; + @@ -8142,1877 +12212,3647 @@ index d2ba140e6f..0000000000 - TP_ARGS(local, sdata) - ); - ---TRACE_EVENT(drv_sta_set_4addr, --+DECLARE_EVENT_CLASS(sta_flag_evt, -- TP_PROTO(struct ieee80211_local *local, -- struct ieee80211_sub_if_data *sdata, -- struct ieee80211_sta *sta, bool enabled), --@@ -2788,6 +2788,22 @@ TRACE_EVENT(drv_sta_set_4addr, -- ) -- ); +--TRACE_EVENT(drv_sta_set_4addr, +-+DECLARE_EVENT_CLASS(sta_flag_evt, +- TP_PROTO(struct ieee80211_local *local, +- struct ieee80211_sub_if_data *sdata, +- struct ieee80211_sta *sta, bool enabled), +-@@ -2788,6 +2788,22 @@ TRACE_EVENT(drv_sta_set_4addr, +- ) +- ); +- +-+DEFINE_EVENT(sta_flag_evt, drv_sta_set_4addr, +-+ TP_PROTO(struct ieee80211_local *local, +-+ struct ieee80211_sub_if_data *sdata, +-+ struct ieee80211_sta *sta, bool enabled), +-+ +-+ TP_ARGS(local, sdata, sta, enabled) +-+); +-+ +-+DEFINE_EVENT(sta_flag_evt, drv_sta_set_decap_offload, +-+ TP_PROTO(struct ieee80211_local *local, +-+ struct ieee80211_sub_if_data *sdata, +-+ struct ieee80211_sta *sta, bool enabled), +-+ +-+ TP_ARGS(local, sdata, sta, enabled) +-+); +-+ +- #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ +- +- #undef TRACE_INCLUDE_PATH +diff --git a/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch b/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch +new file mode 100644 +index 0000000000..362bb885d7 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch +@@ -0,0 +1,99 @@ ++From: Lorenzo Bianconi <lorenzo@kernel.org> ++Date: Wed, 3 Nov 2021 18:02:35 +0100 ++Subject: [PATCH] cfg80211: fix possible NULL pointer dereference in ++ cfg80211_stop_offchan_radar_detection ++ ++Fix the following NULL pointer dereference in ++cfg80211_stop_offchan_radar_detection routine that occurs when hostapd ++is stopped during the CAC on offchannel chain: ++ ++Sat Jan 1 0[ 779.567851] ESR = 0x96000005 ++0:12:50 2000 dae[ 779.572346] EC = 0x25: DABT (current EL), IL = 32 bits ++mon.debug hostap[ 779.578984] SET = 0, FnV = 0 ++d: hostapd_inter[ 779.583445] EA = 0, S1PTW = 0 ++face_deinit_free[ 779.587936] Data abort info: ++: num_bss=1 conf[ 779.592224] ISV = 0, ISS = 0x00000005 ++->num_bss=1 ++Sat[ 779.597403] CM = 0, WnR = 0 ++ Jan 1 00:12:50[ 779.601749] user pgtable: 4k pages, 39-bit VAs, pgdp=00000000418b2000 ++ 2000 daemon.deb[ 779.609601] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 ++ug hostapd: host[ 779.619657] Internal error: Oops: 96000005 [#1] SMP ++[ 779.770810] CPU: 0 PID: 2202 Comm: hostapd Not tainted 5.10.75 #0 ++[ 779.776892] Hardware name: MediaTek MT7622 RFB1 board (DT) ++[ 779.782370] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) ++[ 779.788384] pc : cfg80211_chandef_valid+0x10/0x490 [cfg80211] ++[ 779.794128] lr : cfg80211_check_station_change+0x3190/0x3950 [cfg80211] ++[ 779.800731] sp : ffffffc01204b7e0 ++[ 779.804036] x29: ffffffc01204b7e0 x28: ffffff80039bdc00 ++[ 779.809340] x27: 0000000000000000 x26: ffffffc008cb3050 ++[ 779.814644] x25: 0000000000000000 x24: 0000000000000002 ++[ 779.819948] x23: ffffff8002630000 x22: ffffff8003e748d0 ++[ 779.825252] x21: 0000000000000cc0 x20: ffffff8003da4a00 ++[ 779.830556] x19: 0000000000000000 x18: ffffff8001bf7ce0 ++[ 779.835860] x17: 00000000ffffffff x16: 0000000000000000 ++[ 779.841164] x15: 0000000040d59200 x14: 00000000000019c0 ++[ 779.846467] x13: 00000000000001c8 x12: 000636b9e9dab1c6 ++[ 779.851771] x11: 0000000000000141 x10: 0000000000000820 ++[ 779.857076] x9 : 0000000000000000 x8 : ffffff8003d7d038 ++[ 779.862380] x7 : 0000000000000000 x6 : ffffff8003d7d038 ++[ 779.867683] x5 : 0000000000000e90 x4 : 0000000000000038 ++[ 779.872987] x3 : 0000000000000002 x2 : 0000000000000004 ++[ 779.878291] x1 : 0000000000000000 x0 : 0000000000000000 ++[ 779.883594] Call trace: ++[ 779.886039] cfg80211_chandef_valid+0x10/0x490 [cfg80211] ++[ 779.891434] cfg80211_check_station_change+0x3190/0x3950 [cfg80211] ++[ 779.897697] nl80211_radar_notify+0x138/0x19c [cfg80211] ++[ 779.903005] cfg80211_stop_offchan_radar_detection+0x7c/0x8c [cfg80211] ++[ 779.909616] __cfg80211_leave+0x2c/0x190 [cfg80211] ++[ 779.914490] cfg80211_register_netdevice+0x1c0/0x6d0 [cfg80211] ++[ 779.920404] raw_notifier_call_chain+0x50/0x70 ++[ 779.924841] call_netdevice_notifiers_info+0x54/0xa0 ++[ 779.929796] __dev_close_many+0x40/0x100 ++[ 779.933712] __dev_change_flags+0x98/0x190 ++[ 779.937800] dev_change_flags+0x20/0x60 ++[ 779.941628] devinet_ioctl+0x534/0x6d0 ++[ 779.945370] inet_ioctl+0x1bc/0x230 ++[ 779.948849] sock_do_ioctl+0x44/0x200 ++[ 779.952502] sock_ioctl+0x268/0x4c0 ++[ 779.955985] __arm64_sys_ioctl+0xac/0xd0 ++[ 779.959900] el0_svc_common.constprop.0+0x60/0x110 ++[ 779.964682] do_el0_svc+0x1c/0x24 ++[ 779.967990] el0_svc+0x10/0x1c ++[ 779.971036] el0_sync_handler+0x9c/0x120 ++[ 779.974950] el0_sync+0x148/0x180 ++[ 779.978259] Code: a9bc7bfd 910003fd a90153f3 aa0003f3 (f9400000) ++[ 779.984344] ---[ end trace 0e67b4f5d6cdeec7 ]--- ++[ 779.996400] Kernel panic - not syncing: Oops: Fatal exception ++[ 780.002139] SMP: stopping secondary CPUs ++[ 780.006057] Kernel Offset: disabled ++[ 780.009537] CPU features: 0x0000002,04002004 ++[ 780.013796] Memory Limit: none ++ ++Fixes: b8f5facf286b ("cfg80211: implement APIs for dedicated radar detection HW") ++Reported-by: Evelyn Tsai <evelyn.tsai@mediatek.com> ++Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com> ++Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Link: https://lore.kernel.org/r/c2e34c065bf8839c5ffa45498ae154021a72a520.1635958796.git.lorenzo@kernel.org ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++--- ++ ++--- a/net/wireless/mlme.c +++++ b/net/wireless/mlme.c ++@@ -982,6 +982,9 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ ++ lockdep_assert_wiphy(&rdev->wiphy); ++ +++ if (!cfg80211_chandef_valid(chandef)) +++ return; +++ ++ if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) ++ return; ++ ++@@ -1096,6 +1099,6 @@ void cfg80211_stop_offchan_radar_detecti ++ ++ rdev_set_radar_offchan(rdev, NULL); ++ ++- __cfg80211_offchan_cac_event(rdev, NULL, NULL, +++ __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, ++ NL80211_RADAR_CAC_ABORTED); ++ } +diff --git a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch b/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch +deleted file mode 100644 +index 91987ed759..0000000000 +--- a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch ++++ /dev/null +@@ -1,116 +0,0 @@ +-From: Markus Theil <markus.theil@tu-ilmenau.de> +-Date: Sat, 6 Feb 2021 12:51:12 +0100 +-Subject: [PATCH] mac80211: enable QoS support for nl80211 ctrl port +- +-This patch unifies sending control port frames +-over nl80211 and AF_PACKET sockets a little more. +- +-Before this patch, EAPOL frames got QoS prioritization +-only when using AF_PACKET sockets. +- +-__ieee80211_select_queue only selects a QoS-enabled queue +-for control port frames, when the control port protocol +-is set correctly on the skb. For the AF_PACKET path this +-works, but the nl80211 path used ETH_P_802_3. +- +-Another check for injected frames in wme.c then prevented +-the QoS TID to be copied in the frame. +- +-In order to fix this, get rid of the frame injection marking +-for nl80211 ctrl port and set the correct ethernet protocol. +- +-Please note: +-An erlier version of this path tried to prevent +-frame aggregation for control port frames in order to speed up +-the initial connection setup a little. This seemed to cause +-issues on my older Intel dvm-based hardware, and was therefore +-removed again. Future commits which try to reintroduce this +-have to check carefully how hw behaves with aggregated and +-non-aggregated traffic for the same TID. +-My NIC: Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74 +- +-Reported-by: kernel test robot <lkp@intel.com> +-Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de> +-Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de +-Signed-off-by: Johannes Berg <johannes.berg@intel.com> +---- +- +---- a/net/mac80211/status.c +-+++ b/net/mac80211/status.c +-@@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(str +- u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie; +- struct ieee80211_sub_if_data *sdata; +- struct ieee80211_hdr *hdr = (void *)skb->data; +-- __be16 ethertype = 0; +-- +-- if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3)) +-- skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN); +- +- rcu_read_lock(); +- sdata = ieee80211_sdata_from_skb(local, skb); +- if (sdata) { +-- if (ethertype == sdata->control_port_protocol || +-- ethertype == cpu_to_be16(ETH_P_PREAUTH)) +-+ if (skb->protocol == sdata->control_port_protocol || +-+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) +- cfg80211_control_port_tx_status(&sdata->wdev, +- cookie, +- skb->data, +---- a/net/mac80211/tx.c +-+++ b/net/mac80211/tx.c +-@@ -1195,9 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su +- tx->sta = rcu_dereference(sdata->u.vlan.sta); +- if (!tx->sta && sdata->wdev.use_4addr) +- return TX_DROP; +-- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX | +-- IEEE80211_TX_CTL_INJECTED) || +-- tx->sdata->control_port_protocol == tx->skb->protocol) { +-+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) { +- tx->sta = sta_info_get_bss(sdata, hdr->addr1); +- } +- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) +-@@ -5455,6 +5453,7 @@ int ieee80211_tx_control_port(struct wip +- { +- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); +- struct ieee80211_local *local = sdata->local; +-+ struct sta_info *sta; +- struct sk_buff *skb; +- struct ethhdr *ehdr; +- u32 ctrl_flags = 0; +-@@ -5477,8 +5476,7 @@ int ieee80211_tx_control_port(struct wip +- if (cookie) +- ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; +- +-- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX | +-- IEEE80211_TX_CTL_INJECTED; +-+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX; - --+DEFINE_EVENT(sta_flag_evt, drv_sta_set_4addr, --+ TP_PROTO(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ struct ieee80211_sta *sta, bool enabled), +- skb = dev_alloc_skb(local->hw.extra_tx_headroom + +- sizeof(struct ethhdr) + len); +-@@ -5495,10 +5493,25 @@ int ieee80211_tx_control_port(struct wip +- ehdr->h_proto = proto; +- +- skb->dev = dev; +-- skb->protocol = htons(ETH_P_802_3); +-+ skb->protocol = proto; +- skb_reset_network_header(skb); +- skb_reset_mac_header(skb); +- +-+ /* update QoS header to prioritize control port frames if possible, +-+ * priorization also happens for control port frames send over +-+ * AF_PACKET +-+ */ +-+ rcu_read_lock(); -+ --+ TP_ARGS(local, sdata, sta, enabled) --+); +-+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) { +-+ u16 queue = __ieee80211_select_queue(sdata, sta, skb); -+ --+DEFINE_EVENT(sta_flag_evt, drv_sta_set_decap_offload, --+ TP_PROTO(struct ieee80211_local *local, --+ struct ieee80211_sub_if_data *sdata, --+ struct ieee80211_sta *sta, bool enabled), +-+ skb_set_queue_mapping(skb, queue); +-+ skb_get_hash(skb); +-+ } -+ --+ TP_ARGS(local, sdata, sta, enabled) --+); +-+ rcu_read_unlock(); -+ -- #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ +- /* mutex lock is only needed for incrementing the cookie counter */ +- mutex_lock(&local->mtx); - -- #undef TRACE_INCLUDE_PATH -diff --git a/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch b/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch +diff --git a/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch b/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch +new file mode 100644 +index 0000000000..df7afefb34 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch +@@ -0,0 +1,136 @@ ++From: Lorenzo Bianconi <lorenzo@kernel.org> ++Date: Tue, 16 Nov 2021 12:41:52 +0100 ++Subject: [PATCH] cfg80211: schedule offchan_cac_abort_wk in ++ cfg80211_radar_event ++ ++If necessary schedule offchan_cac_abort_wk work in cfg80211_radar_event ++routine adding offchan parameter to cfg80211_radar_event signature. ++Rename cfg80211_radar_event in __cfg80211_radar_event and introduce ++the two following inline helpers: ++- cfg80211_radar_event ++- cfg80211_offchan_radar_event ++Doing so the drv will not need to run cfg80211_offchan_cac_abort() after ++radar detection on the offchannel chain. ++ ++Tested-by: Owen Peng <owen.peng@mediatek.com> ++Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Link: https://lore.kernel.org/r/3ff583e021e3343a3ced54a7b09b5e184d1880dc.1637062727.git.lorenzo@kernel.org ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++--- ++ ++--- a/include/net/cfg80211.h +++++ b/include/net/cfg80211.h ++@@ -7580,15 +7580,33 @@ void cfg80211_cqm_txe_notify(struct net_ ++ void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp); ++ ++ /** ++- * cfg80211_radar_event - radar detection event +++ * __cfg80211_radar_event - radar detection event ++ * @wiphy: the wiphy ++ * @chandef: chandef for the current channel +++ * @offchan: the radar has been detected on the offchannel chain ++ * @gfp: context flags ++ * ++ * This function is called when a radar is detected on the current chanenl. ++ */ ++-void cfg80211_radar_event(struct wiphy *wiphy, ++- struct cfg80211_chan_def *chandef, gfp_t gfp); +++void __cfg80211_radar_event(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef, +++ bool offchan, gfp_t gfp); +++ +++static inline void +++cfg80211_radar_event(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef, +++ gfp_t gfp) +++{ +++ __cfg80211_radar_event(wiphy, chandef, false, gfp); +++} +++ +++static inline void +++cfg80211_offchan_radar_event(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef, +++ gfp_t gfp) +++{ +++ __cfg80211_radar_event(wiphy, chandef, true, gfp); +++} ++ ++ /** ++ * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event ++--- a/net/wireless/mlme.c +++++ b/net/wireless/mlme.c ++@@ -905,13 +905,13 @@ void cfg80211_dfs_channels_update_work(s ++ } ++ ++ ++-void cfg80211_radar_event(struct wiphy *wiphy, ++- struct cfg80211_chan_def *chandef, ++- gfp_t gfp) +++void __cfg80211_radar_event(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef, +++ bool offchan, gfp_t gfp) ++ { ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ ++- trace_cfg80211_radar_event(wiphy, chandef); +++ trace_cfg80211_radar_event(wiphy, chandef, offchan); ++ ++ /* only set the chandef supplied channel to unavailable, in ++ * case the radar is detected on only one of multiple channels ++@@ -919,6 +919,9 @@ void cfg80211_radar_event(struct wiphy * ++ */ ++ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); ++ +++ if (offchan) +++ queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); +++ ++ cfg80211_sched_dfs_chan_update(rdev); ++ ++ nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp); ++@@ -926,7 +929,7 @@ void cfg80211_radar_event(struct wiphy * ++ memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def)); ++ queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk); ++ } ++-EXPORT_SYMBOL(cfg80211_radar_event); +++EXPORT_SYMBOL(__cfg80211_radar_event); ++ ++ void cfg80211_cac_event(struct net_device *netdev, ++ const struct cfg80211_chan_def *chandef, ++@@ -998,7 +1001,8 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ rdev->offchan_radar_wdev = NULL; ++ break; ++ case NL80211_RADAR_CAC_ABORTED: ++- cancel_delayed_work(&rdev->offchan_cac_done_wk); +++ if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) +++ return; ++ wdev = rdev->offchan_radar_wdev; ++ rdev->offchan_radar_wdev = NULL; ++ break; ++--- a/net/wireless/trace.h +++++ b/net/wireless/trace.h ++@@ -3022,18 +3022,21 @@ TRACE_EVENT(cfg80211_ch_switch_started_n ++ ); ++ ++ TRACE_EVENT(cfg80211_radar_event, ++- TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), ++- TP_ARGS(wiphy, chandef), +++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, +++ bool offchan), +++ TP_ARGS(wiphy, chandef, offchan), ++ TP_STRUCT__entry( ++ WIPHY_ENTRY ++ CHAN_DEF_ENTRY +++ __field(bool, offchan) ++ ), ++ TP_fast_assign( ++ WIPHY_ASSIGN; ++ CHAN_DEF_ASSIGN(chandef); +++ __entry->offchan = offchan; ++ ), ++- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, ++- WIPHY_PR_ARG, CHAN_DEF_PR_ARG) +++ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", offchan %d", +++ WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->offchan) ++ ); ++ ++ TRACE_EVENT(cfg80211_cac_event, +diff --git a/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch b/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch +new file mode 100644 +index 0000000000..a1b6e3c80d +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch +@@ -0,0 +1,220 @@ ++From: Lorenzo Bianconi <lorenzo@kernel.org> ++Date: Tue, 16 Nov 2021 15:03:36 +0100 ++Subject: [PATCH] cfg80211: allow continuous radar monitoring on offchannel ++ chain ++ ++Allow continuous radar detection on the offchannel chain in order ++to switch to the monitored channel whenever the underlying driver ++reports a radar pattern on the main channel. ++ ++Tested-by: Owen Peng <owen.peng@mediatek.com> ++Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Link: https://lore.kernel.org/r/d46217310a49b14ff0e9c002f0a6e0547d70fd2c.1637071350.git.lorenzo@kernel.org ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++--- ++ ++--- a/net/wireless/chan.c +++++ b/net/wireless/chan.c ++@@ -712,6 +712,19 @@ static bool cfg80211_is_wiphy_oper_chan( ++ return false; ++ } ++ +++static bool +++cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, +++ struct ieee80211_channel *channel) +++{ +++ if (!rdev->offchan_radar_wdev) +++ return false; +++ +++ if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) +++ return false; +++ +++ return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); +++} +++ ++ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, ++ struct ieee80211_channel *chan) ++ { ++@@ -728,6 +741,9 @@ bool cfg80211_any_wiphy_oper_chan(struct ++ ++ if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan)) ++ return true; +++ +++ if (cfg80211_offchan_chain_is_active(rdev, chan)) +++ return true; ++ } ++ ++ return false; ++--- a/net/wireless/mlme.c +++++ b/net/wireless/mlme.c ++@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ if (!cfg80211_chandef_valid(chandef)) ++ return; ++ ++- if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) +++ if (!rdev->offchan_radar_wdev) ++ return; ++ ++ switch (event) { ++@@ -998,17 +998,13 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); ++ cfg80211_sched_dfs_chan_update(rdev); ++ wdev = rdev->offchan_radar_wdev; ++- rdev->offchan_radar_wdev = NULL; ++ break; ++ case NL80211_RADAR_CAC_ABORTED: ++ if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) ++ return; ++ wdev = rdev->offchan_radar_wdev; ++- rdev->offchan_radar_wdev = NULL; ++ break; ++ case NL80211_RADAR_CAC_STARTED: ++- WARN_ON(!wdev); ++- rdev->offchan_radar_wdev = wdev; ++ break; ++ default: ++ return; ++@@ -1024,7 +1020,8 @@ cfg80211_offchan_cac_event(struct cfg802 ++ enum nl80211_radar_event event) ++ { ++ wiphy_lock(&rdev->wiphy); ++- __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); +++ __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, +++ chandef, event); ++ wiphy_unlock(&rdev->wiphy); ++ } ++ ++@@ -1071,7 +1068,13 @@ cfg80211_start_offchan_radar_detection(s ++ NL80211_EXT_FEATURE_RADAR_OFFCHAN)) ++ return -EOPNOTSUPP; ++ ++- if (rdev->offchan_radar_wdev) +++ /* Offchannel chain already locked by another wdev */ +++ if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) +++ return -EBUSY; +++ +++ /* CAC already in progress on the offchannel chain */ +++ if (rdev->offchan_radar_wdev == wdev && +++ delayed_work_pending(&rdev->offchan_cac_done_wk)) ++ return -EBUSY; ++ ++ err = rdev_set_radar_offchan(rdev, chandef); ++@@ -1083,6 +1086,8 @@ cfg80211_start_offchan_radar_detection(s ++ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; ++ ++ rdev->offchan_radar_chandef = *chandef; +++ rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ +++ ++ __cfg80211_offchan_cac_event(rdev, wdev, chandef, ++ NL80211_RADAR_CAC_STARTED); ++ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, ++@@ -1102,6 +1107,7 @@ void cfg80211_stop_offchan_radar_detecti ++ return; ++ ++ rdev_set_radar_offchan(rdev, NULL); +++ rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ ++ ++ __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, ++ NL80211_RADAR_CAC_ABORTED); ++--- a/net/wireless/nl80211.c +++++ b/net/wireless/nl80211.c ++@@ -9278,42 +9278,60 @@ static int nl80211_start_radar_detection ++ struct cfg80211_chan_def chandef; ++ enum nl80211_dfs_regions dfs_region; ++ unsigned int cac_time_ms; ++- int err; +++ int err = -EINVAL; +++ +++ flush_delayed_work(&rdev->dfs_update_channels_wk); +++ +++ wiphy_lock(wiphy); ++ ++ dfs_region = reg_get_dfs_region(wiphy); ++ if (dfs_region == NL80211_DFS_UNSET) ++- return -EINVAL; +++ goto unlock; ++ ++ err = nl80211_parse_chandef(rdev, info, &chandef); ++ if (err) ++- return err; +++ goto unlock; ++ ++ err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); ++ if (err < 0) ++- return err; +++ goto unlock; ++ ++- if (err == 0) ++- return -EINVAL; +++ if (err == 0) { +++ err = -EINVAL; +++ goto unlock; +++ } ++ ++- if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) ++- return -EINVAL; +++ if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) { +++ err = -EINVAL; +++ goto unlock; +++ } ++ ++- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) ++- return cfg80211_start_offchan_radar_detection(rdev, wdev, ++- &chandef); +++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { +++ err = cfg80211_start_offchan_radar_detection(rdev, wdev, +++ &chandef); +++ goto unlock; +++ } ++ ++- if (netif_carrier_ok(dev)) ++- return -EBUSY; +++ if (netif_carrier_ok(dev)) { +++ err = -EBUSY; +++ goto unlock; +++ } ++ ++- if (wdev->cac_started) ++- return -EBUSY; +++ if (wdev->cac_started) { +++ err = -EBUSY; +++ goto unlock; +++ } ++ ++ /* CAC start is offloaded to HW and can't be started manually */ ++- if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) ++- return -EOPNOTSUPP; +++ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) { +++ err = -EOPNOTSUPP; +++ goto unlock; +++ } ++ ++- if (!rdev->ops->start_radar_detection) ++- return -EOPNOTSUPP; +++ if (!rdev->ops->start_radar_detection) { +++ err = -EOPNOTSUPP; +++ goto unlock; +++ } ++ ++ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); ++ if (WARN_ON(!cac_time_ms)) ++@@ -9326,6 +9344,9 @@ static int nl80211_start_radar_detection ++ wdev->cac_start_time = jiffies; ++ wdev->cac_time_ms = cac_time_ms; ++ } +++unlock: +++ wiphy_unlock(wiphy); +++ ++ return err; ++ } ++ ++@@ -15961,7 +15982,8 @@ static const struct genl_small_ops nl802 ++ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, ++ .doit = nl80211_start_radar_detection, ++ .flags = GENL_UNS_ADMIN_PERM, ++- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP, +++ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | +++ NL80211_FLAG_NO_WIPHY_MTX, ++ }, ++ { ++ .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES, +diff --git a/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch b/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch new file mode 100644 -index 0000000000..362bb885d7 +index 0000000000..eb80afbccb --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/316-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch -@@ -0,0 +1,99 @@ ++++ b/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch +@@ -0,0 +1,67 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Wed, 3 Nov 2021 18:02:35 +0100 -+Subject: [PATCH] cfg80211: fix possible NULL pointer dereference in -+ cfg80211_stop_offchan_radar_detection -+ -+Fix the following NULL pointer dereference in -+cfg80211_stop_offchan_radar_detection routine that occurs when hostapd -+is stopped during the CAC on offchannel chain: ++Date: Sat, 23 Oct 2021 11:10:51 +0200 ++Subject: [PATCH] mac80211: introduce set_radar_offchan callback + -+Sat Jan 1 0[ 779.567851] ESR = 0x96000005 -+0:12:50 2000 dae[ 779.572346] EC = 0x25: DABT (current EL), IL = 32 bits -+mon.debug hostap[ 779.578984] SET = 0, FnV = 0 -+d: hostapd_inter[ 779.583445] EA = 0, S1PTW = 0 -+face_deinit_free[ 779.587936] Data abort info: -+: num_bss=1 conf[ 779.592224] ISV = 0, ISS = 0x00000005 -+->num_bss=1 -+Sat[ 779.597403] CM = 0, WnR = 0 -+ Jan 1 00:12:50[ 779.601749] user pgtable: 4k pages, 39-bit VAs, pgdp=00000000418b2000 -+ 2000 daemon.deb[ 779.609601] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 -+ug hostapd: host[ 779.619657] Internal error: Oops: 96000005 [#1] SMP -+[ 779.770810] CPU: 0 PID: 2202 Comm: hostapd Not tainted 5.10.75 #0 -+[ 779.776892] Hardware name: MediaTek MT7622 RFB1 board (DT) -+[ 779.782370] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) -+[ 779.788384] pc : cfg80211_chandef_valid+0x10/0x490 [cfg80211] -+[ 779.794128] lr : cfg80211_check_station_change+0x3190/0x3950 [cfg80211] -+[ 779.800731] sp : ffffffc01204b7e0 -+[ 779.804036] x29: ffffffc01204b7e0 x28: ffffff80039bdc00 -+[ 779.809340] x27: 0000000000000000 x26: ffffffc008cb3050 -+[ 779.814644] x25: 0000000000000000 x24: 0000000000000002 -+[ 779.819948] x23: ffffff8002630000 x22: ffffff8003e748d0 -+[ 779.825252] x21: 0000000000000cc0 x20: ffffff8003da4a00 -+[ 779.830556] x19: 0000000000000000 x18: ffffff8001bf7ce0 -+[ 779.835860] x17: 00000000ffffffff x16: 0000000000000000 -+[ 779.841164] x15: 0000000040d59200 x14: 00000000000019c0 -+[ 779.846467] x13: 00000000000001c8 x12: 000636b9e9dab1c6 -+[ 779.851771] x11: 0000000000000141 x10: 0000000000000820 -+[ 779.857076] x9 : 0000000000000000 x8 : ffffff8003d7d038 -+[ 779.862380] x7 : 0000000000000000 x6 : ffffff8003d7d038 -+[ 779.867683] x5 : 0000000000000e90 x4 : 0000000000000038 -+[ 779.872987] x3 : 0000000000000002 x2 : 0000000000000004 -+[ 779.878291] x1 : 0000000000000000 x0 : 0000000000000000 -+[ 779.883594] Call trace: -+[ 779.886039] cfg80211_chandef_valid+0x10/0x490 [cfg80211] -+[ 779.891434] cfg80211_check_station_change+0x3190/0x3950 [cfg80211] -+[ 779.897697] nl80211_radar_notify+0x138/0x19c [cfg80211] -+[ 779.903005] cfg80211_stop_offchan_radar_detection+0x7c/0x8c [cfg80211] -+[ 779.909616] __cfg80211_leave+0x2c/0x190 [cfg80211] -+[ 779.914490] cfg80211_register_netdevice+0x1c0/0x6d0 [cfg80211] -+[ 779.920404] raw_notifier_call_chain+0x50/0x70 -+[ 779.924841] call_netdevice_notifiers_info+0x54/0xa0 -+[ 779.929796] __dev_close_many+0x40/0x100 -+[ 779.933712] __dev_change_flags+0x98/0x190 -+[ 779.937800] dev_change_flags+0x20/0x60 -+[ 779.941628] devinet_ioctl+0x534/0x6d0 -+[ 779.945370] inet_ioctl+0x1bc/0x230 -+[ 779.948849] sock_do_ioctl+0x44/0x200 -+[ 779.952502] sock_ioctl+0x268/0x4c0 -+[ 779.955985] __arm64_sys_ioctl+0xac/0xd0 -+[ 779.959900] el0_svc_common.constprop.0+0x60/0x110 -+[ 779.964682] do_el0_svc+0x1c/0x24 -+[ 779.967990] el0_svc+0x10/0x1c -+[ 779.971036] el0_sync_handler+0x9c/0x120 -+[ 779.974950] el0_sync+0x148/0x180 -+[ 779.978259] Code: a9bc7bfd 910003fd a90153f3 aa0003f3 (f9400000) -+[ 779.984344] ---[ end trace 0e67b4f5d6cdeec7 ]--- -+[ 779.996400] Kernel panic - not syncing: Oops: Fatal exception -+[ 780.002139] SMP: stopping secondary CPUs -+[ 780.006057] Kernel Offset: disabled -+[ 780.009537] CPU features: 0x0000002,04002004 -+[ 780.013796] Memory Limit: none ++Similar to cfg80211, introduce set_radar_offchan callback in mac80211_ops ++in order to configure a dedicated offchannel chain available on some hw ++(e.g. mt7915) to perform offchannel CAC detection and avoid tx/rx downtime. + -+Fixes: b8f5facf286b ("cfg80211: implement APIs for dedicated radar detection HW") -+Reported-by: Evelyn Tsai <evelyn.tsai@mediatek.com> +Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Link: https://lore.kernel.org/r/c2e34c065bf8839c5ffa45498ae154021a72a520.1635958796.git.lorenzo@kernel.org ++Link: https://lore.kernel.org/r/201110606d4f3a7dfdf31440e351f2e2c375d4f0.1634979655.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + -+--- a/net/wireless/mlme.c -++++ b/net/wireless/mlme.c -+@@ -982,6 +982,9 @@ __cfg80211_offchan_cac_event(struct cfg8 -+ -+ lockdep_assert_wiphy(&rdev->wiphy); ++--- a/include/net/mac80211.h +++++ b/include/net/mac80211.h ++@@ -3937,6 +3937,14 @@ struct ieee80211_prep_tx_info { ++ * twt structure. ++ * @twt_teardown_request: Update the hw with TWT teardown request received ++ * from the peer. +++ * @set_radar_offchan: Configure dedicated offchannel chain available for +++ * radar/CAC detection on some hw. This chain can't be used to transmit +++ * or receive frames and it is bounded to a running wdev. +++ * Offchannel radar/CAC detection allows to avoid the CAC downtime +++ * switching to a different channel during CAC detection on the selected +++ * radar channel. +++ * The caller is expected to set chandef pointer to NULL in order to +++ * disable offchannel CAC/radar detection. ++ * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to ++ * resolve a path for hardware flow offloading ++ */ ++@@ -4267,6 +4275,8 @@ struct ieee80211_ops { ++ struct ieee80211_twt_setup *twt); ++ void (*twt_teardown_request)(struct ieee80211_hw *hw, ++ struct ieee80211_sta *sta, u8 flowid); +++ int (*set_radar_offchan)(struct ieee80211_hw *hw, +++ struct cfg80211_chan_def *chandef); ++ #if LINUX_VERSION_IS_GEQ(5,10,0) ++ int (*net_fill_forward_path)(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -4344,6 +4344,18 @@ out: ++ return err; ++ } + -++ if (!cfg80211_chandef_valid(chandef)) -++ return; +++static int +++ieee80211_set_radar_offchan(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef) +++{ +++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ -+ if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) -+ return; -+ -+@@ -1096,6 +1099,6 @@ void cfg80211_stop_offchan_radar_detecti -+ -+ rdev_set_radar_offchan(rdev, NULL); -+ -+- __cfg80211_offchan_cac_event(rdev, NULL, NULL, -++ __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, -+ NL80211_RADAR_CAC_ABORTED); -+ } -diff --git a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch b/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch -deleted file mode 100644 -index 91987ed759..0000000000 ---- a/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch -+++ /dev/null -@@ -1,116 +0,0 @@ --From: Markus Theil <markus.theil@tu-ilmenau.de> --Date: Sat, 6 Feb 2021 12:51:12 +0100 --Subject: [PATCH] mac80211: enable QoS support for nl80211 ctrl port -- --This patch unifies sending control port frames --over nl80211 and AF_PACKET sockets a little more. -- --Before this patch, EAPOL frames got QoS prioritization --only when using AF_PACKET sockets. -- --__ieee80211_select_queue only selects a QoS-enabled queue --for control port frames, when the control port protocol --is set correctly on the skb. For the AF_PACKET path this --works, but the nl80211 path used ETH_P_802_3. -- --Another check for injected frames in wme.c then prevented --the QoS TID to be copied in the frame. -- --In order to fix this, get rid of the frame injection marking --for nl80211 ctrl port and set the correct ethernet protocol. -- --Please note: --An erlier version of this path tried to prevent --frame aggregation for control port frames in order to speed up --the initial connection setup a little. This seemed to cause --issues on my older Intel dvm-based hardware, and was therefore --removed again. Future commits which try to reintroduce this --have to check carefully how hw behaves with aggregated and --non-aggregated traffic for the same TID. --My NIC: Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74 -- --Reported-by: kernel test robot <lkp@intel.com> --Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de> --Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de --Signed-off-by: Johannes Berg <johannes.berg@intel.com> ----- -- ----- a/net/mac80211/status.c --+++ b/net/mac80211/status.c --@@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(str -- u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie; -- struct ieee80211_sub_if_data *sdata; -- struct ieee80211_hdr *hdr = (void *)skb->data; --- __be16 ethertype = 0; --- --- if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3)) --- skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN); -- -- rcu_read_lock(); -- sdata = ieee80211_sdata_from_skb(local, skb); -- if (sdata) { --- if (ethertype == sdata->control_port_protocol || --- ethertype == cpu_to_be16(ETH_P_PREAUTH)) --+ if (skb->protocol == sdata->control_port_protocol || --+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) -- cfg80211_control_port_tx_status(&sdata->wdev, -- cookie, -- skb->data, ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1195,9 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su -- tx->sta = rcu_dereference(sdata->u.vlan.sta); -- if (!tx->sta && sdata->wdev.use_4addr) -- return TX_DROP; --- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX | --- IEEE80211_TX_CTL_INJECTED) || --- tx->sdata->control_port_protocol == tx->skb->protocol) { --+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) { -- tx->sta = sta_info_get_bss(sdata, hdr->addr1); -- } -- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) --@@ -5455,6 +5453,7 @@ int ieee80211_tx_control_port(struct wip -- { -- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -- struct ieee80211_local *local = sdata->local; --+ struct sta_info *sta; -- struct sk_buff *skb; -- struct ethhdr *ehdr; -- u32 ctrl_flags = 0; --@@ -5477,8 +5476,7 @@ int ieee80211_tx_control_port(struct wip -- if (cookie) -- ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; -- --- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX | --- IEEE80211_TX_CTL_INJECTED; --+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX; -- -- skb = dev_alloc_skb(local->hw.extra_tx_headroom + -- sizeof(struct ethhdr) + len); --@@ -5495,10 +5493,25 @@ int ieee80211_tx_control_port(struct wip -- ehdr->h_proto = proto; -- -- skb->dev = dev; --- skb->protocol = htons(ETH_P_802_3); --+ skb->protocol = proto; -- skb_reset_network_header(skb); -- skb_reset_mac_header(skb); -- --+ /* update QoS header to prioritize control port frames if possible, --+ * priorization also happens for control port frames send over --+ * AF_PACKET --+ */ --+ rcu_read_lock(); --+ --+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) { --+ u16 queue = __ieee80211_select_queue(sdata, sta, skb); --+ --+ skb_set_queue_mapping(skb, queue); --+ skb_get_hash(skb); --+ } --+ --+ rcu_read_unlock(); --+ -- /* mutex lock is only needed for incrementing the cookie counter */ -- mutex_lock(&local->mtx); -- -diff --git a/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch b/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch +++ if (!local->ops->set_radar_offchan) +++ return -EOPNOTSUPP; +++ +++ return local->ops->set_radar_offchan(&local->hw, chandef); +++} +++ ++ const struct cfg80211_ops mac80211_config_ops = { ++ .add_virtual_intf = ieee80211_add_iface, ++ .del_virtual_intf = ieee80211_del_iface, ++@@ -4448,4 +4460,5 @@ const struct cfg80211_ops mac80211_confi ++ .reset_tid_config = ieee80211_reset_tid_config, ++ .set_sar_specs = ieee80211_set_sar_specs, ++ .color_change = ieee80211_color_change, +++ .set_radar_offchan = ieee80211_set_radar_offchan, ++ }; +diff --git a/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch b/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch new file mode 100644 -index 0000000000..df7afefb34 +index 0000000000..483b87cd88 --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch -@@ -0,0 +1,136 @@ ++++ b/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch +@@ -0,0 +1,532 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Tue, 16 Nov 2021 12:41:52 +0100 -+Subject: [PATCH] cfg80211: schedule offchan_cac_abort_wk in -+ cfg80211_radar_event ++Date: Mon, 29 Nov 2021 14:11:24 +0100 ++Subject: [PATCH] cfg80211: rename offchannel_chain structs to background_chain ++ to avoid confusion with ETSI standard + -+If necessary schedule offchan_cac_abort_wk work in cfg80211_radar_event -+routine adding offchan parameter to cfg80211_radar_event signature. -+Rename cfg80211_radar_event in __cfg80211_radar_event and introduce -+the two following inline helpers: -+- cfg80211_radar_event -+- cfg80211_offchan_radar_event -+Doing so the drv will not need to run cfg80211_offchan_cac_abort() after -+radar detection on the offchannel chain. ++ETSI standard defines "Offchannel CAC" as: ++"Off-Channel CAC is performed by a number of non-continuous checks ++spread over a period in time. This period, which is required to ++determine the presence of radar signals, is defined as the Off-Channel ++CAC Time.. ++Minimum Off-Channel CAC Time 6 minutes and Maximum Off-Channel CAC Time ++4 hours..". ++mac80211 implementation refers to a dedicated hw chain used for continuous ++radar monitoring. Rename offchannel_* references to background_* in ++order to avoid confusion with ETSI standard. + -+Tested-by: Owen Peng <owen.peng@mediatek.com> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Link: https://lore.kernel.org/r/3ff583e021e3343a3ced54a7b09b5e184d1880dc.1637062727.git.lorenzo@kernel.org ++Link: https://lore.kernel.org/r/4204cc1d648d76b44557981713231e030a3bd991.1638190762.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h -+@@ -7580,15 +7580,33 @@ void cfg80211_cqm_txe_notify(struct net_ -+ void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp); ++@@ -4058,14 +4058,14 @@ struct mgmt_frame_regs { ++ * ++ * @color_change: Initiate a color change. ++ * ++- * @set_radar_offchan: Configure dedicated offchannel chain available for +++ * @set_radar_background: Configure dedicated offchannel chain available for ++ * radar/CAC detection on some hw. This chain can't be used to transmit ++ * or receive frames and it is bounded to a running wdev. ++- * Offchannel radar/CAC detection allows to avoid the CAC downtime +++ * Background radar/CAC detection allows to avoid the CAC downtime ++ * switching to a different channel during CAC detection on the selected ++ * radar channel. ++ * The caller is expected to set chandef pointer to NULL in order to ++- * disable offchannel CAC/radar detection. +++ * disable background CAC/radar detection. ++ */ ++ struct cfg80211_ops { ++ int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ++@@ -4396,8 +4396,8 @@ struct cfg80211_ops { ++ int (*color_change)(struct wiphy *wiphy, ++ struct net_device *dev, ++ struct cfg80211_color_change_settings *params); ++- int (*set_radar_offchan)(struct wiphy *wiphy, ++- struct cfg80211_chan_def *chandef); +++ int (*set_radar_background)(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef); ++ }; ++ ++ /* ++@@ -7601,9 +7601,9 @@ cfg80211_radar_event(struct wiphy *wiphy ++ } ++ ++ static inline void ++-cfg80211_offchan_radar_event(struct wiphy *wiphy, ++- struct cfg80211_chan_def *chandef, ++- gfp_t gfp) +++cfg80211_background_radar_event(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef, +++ gfp_t gfp) ++ { ++ __cfg80211_radar_event(wiphy, chandef, true, gfp); ++ } ++@@ -7638,13 +7638,13 @@ void cfg80211_cac_event(struct net_devic ++ enum nl80211_radar_event event, gfp_t gfp); + + /** -+- * cfg80211_radar_event - radar detection event -++ * __cfg80211_radar_event - radar detection event ++- * cfg80211_offchan_cac_abort - Channel Availability Check offchan abort event +++ * cfg80211_background_cac_abort - Channel Availability Check offchan abort event + * @wiphy: the wiphy -+ * @chandef: chandef for the current channel -++ * @offchan: the radar has been detected on the offchannel chain -+ * @gfp: context flags + * -+ * This function is called when a radar is detected on the current chanenl. ++ * This function is called by the driver when a Channel Availability Check ++ * (CAC) is aborted by a offchannel dedicated chain. + */ -+-void cfg80211_radar_event(struct wiphy *wiphy, -+- struct cfg80211_chan_def *chandef, gfp_t gfp); -++void __cfg80211_radar_event(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef, -++ bool offchan, gfp_t gfp); -++ -++static inline void -++cfg80211_radar_event(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef, -++ gfp_t gfp) -++{ -++ __cfg80211_radar_event(wiphy, chandef, false, gfp); -++} -++ -++static inline void -++cfg80211_offchan_radar_event(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef, -++ gfp_t gfp) -++{ -++ __cfg80211_radar_event(wiphy, chandef, true, gfp); -++} ++-void cfg80211_offchan_cac_abort(struct wiphy *wiphy); +++void cfg80211_background_cac_abort(struct wiphy *wiphy); + + /** -+ * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event -+--- a/net/wireless/mlme.c -++++ b/net/wireless/mlme.c -+@@ -905,13 +905,13 @@ void cfg80211_dfs_channels_update_work(s -+ } ++ * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying ++--- a/include/net/mac80211.h +++++ b/include/net/mac80211.h ++@@ -3937,14 +3937,14 @@ struct ieee80211_prep_tx_info { ++ * twt structure. ++ * @twt_teardown_request: Update the hw with TWT teardown request received ++ * from the peer. ++- * @set_radar_offchan: Configure dedicated offchannel chain available for +++ * @set_radar_background: Configure dedicated offchannel chain available for ++ * radar/CAC detection on some hw. This chain can't be used to transmit ++ * or receive frames and it is bounded to a running wdev. ++- * Offchannel radar/CAC detection allows to avoid the CAC downtime +++ * Background radar/CAC detection allows to avoid the CAC downtime ++ * switching to a different channel during CAC detection on the selected ++ * radar channel. ++ * The caller is expected to set chandef pointer to NULL in order to ++- * disable offchannel CAC/radar detection. +++ * disable background CAC/radar detection. ++ * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to ++ * resolve a path for hardware flow offloading ++ */ ++@@ -4275,8 +4275,8 @@ struct ieee80211_ops { ++ struct ieee80211_twt_setup *twt); ++ void (*twt_teardown_request)(struct ieee80211_hw *hw, ++ struct ieee80211_sta *sta, u8 flowid); ++- int (*set_radar_offchan)(struct ieee80211_hw *hw, ++- struct cfg80211_chan_def *chandef); +++ int (*set_radar_background)(struct ieee80211_hw *hw, +++ struct cfg80211_chan_def *chandef); ++ #if LINUX_VERSION_IS_GEQ(5,10,0) ++ int (*net_fill_forward_path)(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++--- a/include/uapi/linux/nl80211.h +++++ b/include/uapi/linux/nl80211.h ++@@ -2608,10 +2608,10 @@ enum nl80211_commands { ++ * Mandatory parameter for the transmitting interface to enable MBSSID. ++ * Optional for the non-transmitting interfaces. ++ * ++- * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for ++- * radar/CAC detection on some hw. This chain can't be used to transmit ++- * or receive frames and it is bounded to a running wdev. ++- * Offchannel radar/CAC detection allows to avoid the CAC downtime +++ * @NL80211_ATTR_RADAR_BACKGROUND: Configure dedicated offchannel chain +++ * available for radar/CAC detection on some hw. This chain can't be used +++ * to transmit or receive frames and it is bounded to a running wdev. +++ * Background radar/CAC detection allows to avoid the CAC downtime ++ * switching on a different channel during CAC detection on the selected ++ * radar channel. ++ * ++@@ -3121,7 +3121,7 @@ enum nl80211_attrs { ++ NL80211_ATTR_MBSSID_CONFIG, ++ NL80211_ATTR_MBSSID_ELEMS, + ++- NL80211_ATTR_RADAR_OFFCHAN, +++ NL80211_ATTR_RADAR_BACKGROUND, + -+-void cfg80211_radar_event(struct wiphy *wiphy, -+- struct cfg80211_chan_def *chandef, -+- gfp_t gfp) -++void __cfg80211_radar_event(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef, -++ bool offchan, gfp_t gfp) ++ /* add attributes here, update the policy in nl80211.c */ ++ ++@@ -6022,7 +6022,7 @@ enum nl80211_feature_flags { ++ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision ++ * detection and change announcemnts. ++ * ++- * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC +++ * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC ++ * detection. ++ * ++ * @NUM_NL80211_EXT_FEATURES: number of extended features. ++@@ -6090,7 +6090,7 @@ enum nl80211_ext_feature_index { ++ NL80211_EXT_FEATURE_SECURE_RTT, ++ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, ++ NL80211_EXT_FEATURE_BSS_COLOR, ++- NL80211_EXT_FEATURE_RADAR_OFFCHAN, +++ NL80211_EXT_FEATURE_RADAR_BACKGROUND, ++ ++ /* add new features before the definition below */ ++ NUM_NL80211_EXT_FEATURES, ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -4345,15 +4345,15 @@ out: ++ } ++ ++ static int ++-ieee80211_set_radar_offchan(struct wiphy *wiphy, ++- struct cfg80211_chan_def *chandef) +++ieee80211_set_radar_background(struct wiphy *wiphy, +++ struct cfg80211_chan_def *chandef) + { -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ struct ieee80211_local *local = wiphy_priv(wiphy); + -+- trace_cfg80211_radar_event(wiphy, chandef); -++ trace_cfg80211_radar_event(wiphy, chandef, offchan); ++- if (!local->ops->set_radar_offchan) +++ if (!local->ops->set_radar_background) ++ return -EOPNOTSUPP; + -+ /* only set the chandef supplied channel to unavailable, in -+ * case the radar is detected on only one of multiple channels -+@@ -919,6 +919,9 @@ void cfg80211_radar_event(struct wiphy * -+ */ -+ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); ++- return local->ops->set_radar_offchan(&local->hw, chandef); +++ return local->ops->set_radar_background(&local->hw, chandef); ++ } + -++ if (offchan) -++ queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); -++ -+ cfg80211_sched_dfs_chan_update(rdev); ++ const struct cfg80211_ops mac80211_config_ops = { ++@@ -4460,5 +4460,5 @@ const struct cfg80211_ops mac80211_confi ++ .reset_tid_config = ieee80211_reset_tid_config, ++ .set_sar_specs = ieee80211_set_sar_specs, ++ .color_change = ieee80211_color_change, ++- .set_radar_offchan = ieee80211_set_radar_offchan, +++ .set_radar_background = ieee80211_set_radar_background, ++ }; ++--- a/net/wireless/chan.c +++++ b/net/wireless/chan.c ++@@ -716,13 +716,13 @@ static bool ++ cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, ++ struct ieee80211_channel *channel) ++ { ++- if (!rdev->offchan_radar_wdev) +++ if (!rdev->background_radar_wdev) ++ return false; + -+ nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp); -+@@ -926,7 +929,7 @@ void cfg80211_radar_event(struct wiphy * -+ memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def)); -+ queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk); ++- if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) +++ if (!cfg80211_chandef_valid(&rdev->background_radar_chandef)) ++ return false; ++ ++- return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); +++ return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel); + } -+-EXPORT_SYMBOL(cfg80211_radar_event); -++EXPORT_SYMBOL(__cfg80211_radar_event); + -+ void cfg80211_cac_event(struct net_device *netdev, -+ const struct cfg80211_chan_def *chandef, -+@@ -998,7 +1001,8 @@ __cfg80211_offchan_cac_event(struct cfg8 -+ rdev->offchan_radar_wdev = NULL; -+ break; -+ case NL80211_RADAR_CAC_ABORTED: -+- cancel_delayed_work(&rdev->offchan_cac_done_wk); -++ if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) -++ return; -+ wdev = rdev->offchan_radar_wdev; -+ rdev->offchan_radar_wdev = NULL; -+ break; -+--- a/net/wireless/trace.h -++++ b/net/wireless/trace.h -+@@ -3022,18 +3022,21 @@ TRACE_EVENT(cfg80211_ch_switch_started_n -+ ); ++ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, ++--- a/net/wireless/core.c +++++ b/net/wireless/core.c ++@@ -543,9 +543,10 @@ use_default_name: ++ INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); ++ INIT_WORK(&rdev->conn_work, cfg80211_conn_work); ++ INIT_WORK(&rdev->event_work, cfg80211_event_work); ++- INIT_WORK(&rdev->offchan_cac_abort_wk, cfg80211_offchan_cac_abort_wk); ++- INIT_DELAYED_WORK(&rdev->offchan_cac_done_wk, ++- cfg80211_offchan_cac_done_wk); +++ INIT_WORK(&rdev->background_cac_abort_wk, +++ cfg80211_background_cac_abort_wk); +++ INIT_DELAYED_WORK(&rdev->background_cac_done_wk, +++ cfg80211_background_cac_done_wk); + -+ TRACE_EVENT(cfg80211_radar_event, -+- TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), -+- TP_ARGS(wiphy, chandef), -++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, -++ bool offchan), -++ TP_ARGS(wiphy, chandef, offchan), -+ TP_STRUCT__entry( -+ WIPHY_ENTRY -+ CHAN_DEF_ENTRY -++ __field(bool, offchan) -+ ), -+ TP_fast_assign( -+ WIPHY_ASSIGN; -+ CHAN_DEF_ASSIGN(chandef); -++ __entry->offchan = offchan; -+ ), -+- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, -+- WIPHY_PR_ARG, CHAN_DEF_PR_ARG) -++ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", offchan %d", -++ WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->offchan) -+ ); ++ init_waitqueue_head(&rdev->dev_wait); ++ ++@@ -1055,13 +1056,13 @@ void wiphy_unregister(struct wiphy *wiph ++ cancel_work_sync(&rdev->conn_work); ++ flush_work(&rdev->event_work); ++ cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); ++- cancel_delayed_work_sync(&rdev->offchan_cac_done_wk); +++ cancel_delayed_work_sync(&rdev->background_cac_done_wk); ++ flush_work(&rdev->destroy_work); ++ flush_work(&rdev->sched_scan_stop_wk); ++ flush_work(&rdev->propagate_radar_detect_wk); ++ flush_work(&rdev->propagate_cac_done_wk); ++ flush_work(&rdev->mgmt_registrations_update_wk); ++- flush_work(&rdev->offchan_cac_abort_wk); +++ flush_work(&rdev->background_cac_abort_wk); ++ ++ #ifdef CONFIG_PM ++ if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) ++@@ -1210,7 +1211,7 @@ void __cfg80211_leave(struct cfg80211_re ++ ++ cfg80211_pmsr_wdev_down(wdev); ++ ++- cfg80211_stop_offchan_radar_detection(wdev); +++ cfg80211_stop_background_radar_detection(wdev); ++ ++ switch (wdev->iftype) { ++ case NL80211_IFTYPE_ADHOC: ++--- a/net/wireless/core.h +++++ b/net/wireless/core.h ++@@ -84,10 +84,10 @@ struct cfg80211_registered_device { + -+ TRACE_EVENT(cfg80211_cac_event, -diff --git a/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch b/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch -new file mode 100644 -index 0000000000..567743d84d ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/318-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch -@@ -0,0 +1,220 @@ -+From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Tue, 16 Nov 2021 15:03:36 +0100 -+Subject: [PATCH] cfg80211: allow continuous radar monitoring on offchannel -+ chain -+ -+Allow continuous radar detection on the offchannel chain in order -+to switch to the monitored channel whenever the underlying driver -+reports a radar pattern on the main channel. -+ -+Tested-by: Owen Peng <owen.peng@mediatek.com> -+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Link: https://lore.kernel.org/r/d46217310a49b14ff0e9c002f0a6e0547d70fd2c.1637071350.git.lorenzo@kernel.org -+Signed-off-by: Johannes Berg <johannes.berg@intel.com> -+--- -+ -+--- a/net/wireless/chan.c -++++ b/net/wireless/chan.c -+@@ -712,6 +712,19 @@ static bool cfg80211_is_wiphy_oper_chan( -+ return false; -+ } ++ struct delayed_work dfs_update_channels_wk; + -++static bool -++cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, -++ struct ieee80211_channel *channel) -++{ -++ if (!rdev->offchan_radar_wdev) -++ return false; -++ -++ if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) -++ return false; -++ -++ return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); -++} -++ -+ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, -+ struct ieee80211_channel *chan) -+ { -+@@ -728,6 +741,9 @@ bool cfg80211_any_wiphy_oper_chan(struct ++- struct wireless_dev *offchan_radar_wdev; ++- struct cfg80211_chan_def offchan_radar_chandef; ++- struct delayed_work offchan_cac_done_wk; ++- struct work_struct offchan_cac_abort_wk; +++ struct wireless_dev *background_radar_wdev; +++ struct cfg80211_chan_def background_radar_chandef; +++ struct delayed_work background_cac_done_wk; +++ struct work_struct background_cac_abort_wk; + -+ if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan)) -+ return true; -++ -++ if (cfg80211_offchan_chain_is_active(rdev, chan)) -++ return true; -+ } ++ /* netlink port which started critical protocol (0 means not started) */ ++ u32 crit_proto_nlportid; ++@@ -497,15 +497,15 @@ cfg80211_chandef_dfs_cac_time(struct wip ++ void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); + -+ return false; ++ int ++-cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, ++- struct wireless_dev *wdev, ++- struct cfg80211_chan_def *chandef); +++cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, +++ struct wireless_dev *wdev, +++ struct cfg80211_chan_def *chandef); ++ ++-void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); +++void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); ++ ++-void cfg80211_offchan_cac_done_wk(struct work_struct *work); +++void cfg80211_background_cac_done_wk(struct work_struct *work); ++ ++-void cfg80211_offchan_cac_abort_wk(struct work_struct *work); +++void cfg80211_background_cac_abort_wk(struct work_struct *work); ++ ++ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, ++ struct ieee80211_channel *chan); +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c ++@@ -920,7 +920,7 @@ void __cfg80211_radar_event(struct wiphy ++ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); ++ ++ if (offchan) ++- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); +++ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); ++ ++ cfg80211_sched_dfs_chan_update(rdev); ++ ++@@ -975,10 +975,10 @@ void cfg80211_cac_event(struct net_devic ++ EXPORT_SYMBOL(cfg80211_cac_event); ++ ++ static void ++-__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, ++- struct wireless_dev *wdev, ++- const struct cfg80211_chan_def *chandef, ++- enum nl80211_radar_event event) +++__cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, +++ struct wireless_dev *wdev, +++ const struct cfg80211_chan_def *chandef, +++ enum nl80211_radar_event event) ++ { ++ struct wiphy *wiphy = &rdev->wiphy; ++ struct net_device *netdev; +@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 + if (!cfg80211_chandef_valid(chandef)) + return; + -+- if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) -++ if (!rdev->offchan_radar_wdev) ++- if (!rdev->offchan_radar_wdev) +++ if (!rdev->background_radar_wdev) + return; + + switch (event) { -+@@ -998,17 +998,13 @@ __cfg80211_offchan_cac_event(struct cfg8 ++@@ -997,12 +997,12 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef)); + queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); + cfg80211_sched_dfs_chan_update(rdev); -+ wdev = rdev->offchan_radar_wdev; -+- rdev->offchan_radar_wdev = NULL; ++- wdev = rdev->offchan_radar_wdev; +++ wdev = rdev->background_radar_wdev; + break; + case NL80211_RADAR_CAC_ABORTED: -+ if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) ++- if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) +++ if (!cancel_delayed_work(&rdev->background_cac_done_wk)) + return; -+ wdev = rdev->offchan_radar_wdev; -+- rdev->offchan_radar_wdev = NULL; ++- wdev = rdev->offchan_radar_wdev; +++ wdev = rdev->background_radar_wdev; + break; + case NL80211_RADAR_CAC_STARTED: -+- WARN_ON(!wdev); -+- rdev->offchan_radar_wdev = wdev; + break; -+ default: -+ return; -+@@ -1024,7 +1020,8 @@ cfg80211_offchan_cac_event(struct cfg802 -+ enum nl80211_radar_event event) ++@@ -1015,49 +1015,49 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ } ++ ++ static void ++-cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, ++- const struct cfg80211_chan_def *chandef, ++- enum nl80211_radar_event event) +++cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, +++ const struct cfg80211_chan_def *chandef, +++ enum nl80211_radar_event event) + { + wiphy_lock(&rdev->wiphy); -+- __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); -++ __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, -++ chandef, event); ++- __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, ++- chandef, event); +++ __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev, +++ chandef, event); + wiphy_unlock(&rdev->wiphy); + } + -+@@ -1071,7 +1068,13 @@ cfg80211_start_offchan_radar_detection(s -+ NL80211_EXT_FEATURE_RADAR_OFFCHAN)) ++-void cfg80211_offchan_cac_done_wk(struct work_struct *work) +++void cfg80211_background_cac_done_wk(struct work_struct *work) ++ { ++ struct delayed_work *delayed_work = to_delayed_work(work); ++ struct cfg80211_registered_device *rdev; ++ ++ rdev = container_of(delayed_work, struct cfg80211_registered_device, ++- offchan_cac_done_wk); ++- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, ++- NL80211_RADAR_CAC_FINISHED); +++ background_cac_done_wk); +++ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, +++ NL80211_RADAR_CAC_FINISHED); ++ } ++ ++-void cfg80211_offchan_cac_abort_wk(struct work_struct *work) +++void cfg80211_background_cac_abort_wk(struct work_struct *work) ++ { ++ struct cfg80211_registered_device *rdev; ++ ++ rdev = container_of(work, struct cfg80211_registered_device, ++- offchan_cac_abort_wk); ++- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, ++- NL80211_RADAR_CAC_ABORTED); +++ background_cac_abort_wk); +++ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, +++ NL80211_RADAR_CAC_ABORTED); ++ } ++ ++-void cfg80211_offchan_cac_abort(struct wiphy *wiphy) +++void cfg80211_background_cac_abort(struct wiphy *wiphy) ++ { ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ ++- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); +++ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); ++ } ++-EXPORT_SYMBOL(cfg80211_offchan_cac_abort); +++EXPORT_SYMBOL(cfg80211_background_cac_abort); ++ ++ int ++-cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, ++- struct wireless_dev *wdev, ++- struct cfg80211_chan_def *chandef) +++cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, +++ struct wireless_dev *wdev, +++ struct cfg80211_chan_def *chandef) ++ { ++ unsigned int cac_time_ms; ++ int err; ++@@ -1065,19 +1065,19 @@ cfg80211_start_offchan_radar_detection(s ++ lockdep_assert_wiphy(&rdev->wiphy); ++ ++ if (!wiphy_ext_feature_isset(&rdev->wiphy, ++- NL80211_EXT_FEATURE_RADAR_OFFCHAN)) +++ NL80211_EXT_FEATURE_RADAR_BACKGROUND)) + return -EOPNOTSUPP; + -+- if (rdev->offchan_radar_wdev) -++ /* Offchannel chain already locked by another wdev */ -++ if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) -++ return -EBUSY; -++ -++ /* CAC already in progress on the offchannel chain */ -++ if (rdev->offchan_radar_wdev == wdev && -++ delayed_work_pending(&rdev->offchan_cac_done_wk)) ++ /* Offchannel chain already locked by another wdev */ ++- if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) +++ if (rdev->background_radar_wdev && rdev->background_radar_wdev != wdev) + return -EBUSY; + -+ err = rdev_set_radar_offchan(rdev, chandef); -+@@ -1083,6 +1086,8 @@ cfg80211_start_offchan_radar_detection(s ++ /* CAC already in progress on the offchannel chain */ ++- if (rdev->offchan_radar_wdev == wdev && ++- delayed_work_pending(&rdev->offchan_cac_done_wk)) +++ if (rdev->background_radar_wdev == wdev && +++ delayed_work_pending(&rdev->background_cac_done_wk)) ++ return -EBUSY; ++ ++- err = rdev_set_radar_offchan(rdev, chandef); +++ err = rdev_set_radar_background(rdev, chandef); ++ if (err) ++ return err; ++ ++@@ -1085,30 +1085,31 @@ cfg80211_start_offchan_radar_detection(s ++ if (!cac_time_ms) + cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; + -+ rdev->offchan_radar_chandef = *chandef; -++ rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ -++ -+ __cfg80211_offchan_cac_event(rdev, wdev, chandef, -+ NL80211_RADAR_CAC_STARTED); -+ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, -+@@ -1102,6 +1107,7 @@ void cfg80211_stop_offchan_radar_detecti ++- rdev->offchan_radar_chandef = *chandef; ++- rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ +++ rdev->background_radar_chandef = *chandef; +++ rdev->background_radar_wdev = wdev; /* Get offchain ownership */ ++ ++- __cfg80211_offchan_cac_event(rdev, wdev, chandef, ++- NL80211_RADAR_CAC_STARTED); ++- queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, +++ __cfg80211_background_cac_event(rdev, wdev, chandef, +++ NL80211_RADAR_CAC_STARTED); +++ queue_delayed_work(cfg80211_wq, &rdev->background_cac_done_wk, ++ msecs_to_jiffies(cac_time_ms)); ++ ++ return 0; ++ } ++ ++-void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev) +++void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) ++ { ++ struct wiphy *wiphy = wdev->wiphy; ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ ++ lockdep_assert_wiphy(wiphy); ++ ++- if (wdev != rdev->offchan_radar_wdev) +++ if (wdev != rdev->background_radar_wdev) + return; + -+ rdev_set_radar_offchan(rdev, NULL); -++ rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ ++- rdev_set_radar_offchan(rdev, NULL); ++- rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ +++ rdev_set_radar_background(rdev, NULL); +++ rdev->background_radar_wdev = NULL; /* Release offchain ownership */ + -+ __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, -+ NL80211_RADAR_CAC_ABORTED); ++- __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, ++- NL80211_RADAR_CAC_ABORTED); +++ __cfg80211_background_cac_event(rdev, wdev, +++ &rdev->background_radar_chandef, +++ NL80211_RADAR_CAC_ABORTED); ++ } +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c -+@@ -9263,42 +9263,60 @@ static int nl80211_start_radar_detection -+ struct cfg80211_chan_def chandef; -+ enum nl80211_dfs_regions dfs_region; -+ unsigned int cac_time_ms; -+- int err; -++ int err = -EINVAL; -++ -++ flush_delayed_work(&rdev->dfs_update_channels_wk); -++ -++ wiphy_lock(wiphy); -+ -+ dfs_region = reg_get_dfs_region(wiphy); -+ if (dfs_region == NL80211_DFS_UNSET) -+- return -EINVAL; -++ goto unlock; -+ -+ err = nl80211_parse_chandef(rdev, info, &chandef); -+ if (err) -+- return err; -++ goto unlock; -+ -+ err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); -+ if (err < 0) -+- return err; -++ goto unlock; ++@@ -801,7 +801,7 @@ static const struct nla_policy nl80211_p ++ [NL80211_ATTR_MBSSID_CONFIG] = ++ NLA_POLICY_NESTED(nl80211_mbssid_config_policy), ++ [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, ++- [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, +++ [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, ++ }; + -+- if (err == 0) -+- return -EINVAL; -++ if (err == 0) { -++ err = -EINVAL; -++ goto unlock; -++ } ++ /* policy for the key attributes */ ++@@ -9306,9 +9306,9 @@ static int nl80211_start_radar_detection ++ goto unlock; ++ } + -+- if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) -+- return -EINVAL; -++ if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) { -++ err = -EINVAL; -++ goto unlock; -++ } ++- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { ++- err = cfg80211_start_offchan_radar_detection(rdev, wdev, ++- &chandef); +++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) { +++ err = cfg80211_start_background_radar_detection(rdev, wdev, +++ &chandef); ++ goto unlock; ++ } + -+- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) -+- return cfg80211_start_offchan_radar_detection(rdev, wdev, -+- &chandef); -++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { -++ err = cfg80211_start_offchan_radar_detection(rdev, wdev, -++ &chandef); -++ goto unlock; -++ } ++--- a/net/wireless/rdev-ops.h +++++ b/net/wireless/rdev-ops.h ++@@ -1382,17 +1382,17 @@ static inline int rdev_color_change(stru ++ } + -+- if (netif_carrier_ok(dev)) -+- return -EBUSY; -++ if (netif_carrier_ok(dev)) { -++ err = -EBUSY; -++ goto unlock; -++ } ++ static inline int ++-rdev_set_radar_offchan(struct cfg80211_registered_device *rdev, ++- struct cfg80211_chan_def *chandef) +++rdev_set_radar_background(struct cfg80211_registered_device *rdev, +++ struct cfg80211_chan_def *chandef) ++ { ++ struct wiphy *wiphy = &rdev->wiphy; ++ int ret; + -+- if (wdev->cac_started) -+- return -EBUSY; -++ if (wdev->cac_started) { -++ err = -EBUSY; -++ goto unlock; -++ } ++- if (!rdev->ops->set_radar_offchan) +++ if (!rdev->ops->set_radar_background) ++ return -EOPNOTSUPP; + -+ /* CAC start is offloaded to HW and can't be started manually */ -+- if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) -+- return -EOPNOTSUPP; -++ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) { -++ err = -EOPNOTSUPP; -++ goto unlock; -++ } ++- trace_rdev_set_radar_offchan(wiphy, chandef); ++- ret = rdev->ops->set_radar_offchan(wiphy, chandef); +++ trace_rdev_set_radar_background(wiphy, chandef); +++ ret = rdev->ops->set_radar_background(wiphy, chandef); ++ trace_rdev_return_int(wiphy, ret); + -+- if (!rdev->ops->start_radar_detection) -+- return -EOPNOTSUPP; -++ if (!rdev->ops->start_radar_detection) { -++ err = -EOPNOTSUPP; -++ goto unlock; -++ } ++ return ret; ++--- a/net/wireless/trace.h +++++ b/net/wireless/trace.h ++@@ -3646,7 +3646,7 @@ TRACE_EVENT(cfg80211_bss_color_notify, ++ __entry->color_bitmap) ++ ); + -+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); -+ if (WARN_ON(!cac_time_ms)) -+@@ -9311,6 +9329,9 @@ static int nl80211_start_radar_detection -+ wdev->cac_start_time = jiffies; -+ wdev->cac_time_ms = cac_time_ms; -+ } -++unlock: -++ wiphy_unlock(wiphy); -++ -+ return err; -+ } ++-TRACE_EVENT(rdev_set_radar_offchan, +++TRACE_EVENT(rdev_set_radar_background, ++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), + -+@@ -15941,7 +15962,8 @@ static const struct genl_small_ops nl802 -+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, -+ .doit = nl80211_start_radar_detection, -+ .flags = GENL_UNS_ADMIN_PERM, -+- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP, -++ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | -++ NL80211_FLAG_NO_WIPHY_MTX, -+ }, -+ { -+ .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES, -diff --git a/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch b/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch ++ TP_ARGS(wiphy, chandef), +diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch new file mode 100644 -index 0000000000..eb80afbccb +index 0000000000..a135e3d1b5 --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/319-mac80211-introduce-set_radar_offchan-callback.patch -@@ -0,0 +1,67 @@ -+From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Sat, 23 Oct 2021 11:10:51 +0200 -+Subject: [PATCH] mac80211: introduce set_radar_offchan callback ++++ b/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch +@@ -0,0 +1,144 @@ ++From: John Crispin <john@phrozen.org> ++Date: Wed, 15 Sep 2021 19:54:35 -0700 ++Subject: [PATCH] mac80211: MBSSID support in interface handling + -+Similar to cfg80211, introduce set_radar_offchan callback in mac80211_ops -+in order to configure a dedicated offchannel chain available on some hw -+(e.g. mt7915) to perform offchannel CAC detection and avoid tx/rx downtime. ++Configure multiple BSSID and enhanced multi-BSSID advertisement (EMA) ++parameters in mac80211 for AP mode. + -+Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com> -+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Link: https://lore.kernel.org/r/201110606d4f3a7dfdf31440e351f2e2c375d4f0.1634979655.git.lorenzo@kernel.org ++For each interface, 'mbssid_tx_vif' points to the transmitting interface of ++the MBSSID set. The pointer is set to NULL if MBSSID is disabled. ++ ++Function ieee80211_stop() is modified to always bring down all the ++non-transmitting interfaces first and the transmitting interface last. ++ ++Signed-off-by: John Crispin <john@phrozen.org> ++Co-developed-by: Aloka Dixit <alokad@codeaurora.org> ++Signed-off-by: Aloka Dixit <alokad@codeaurora.org> ++Link: https://lore.kernel.org/r/20210916025437.29138-3-alokad@codeaurora.org ++[slightly change logic to be more obvious] +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h -+@@ -3937,6 +3937,14 @@ struct ieee80211_prep_tx_info { -+ * twt structure. -+ * @twt_teardown_request: Update the hw with TWT teardown request received -+ * from the peer. -++ * @set_radar_offchan: Configure dedicated offchannel chain available for -++ * radar/CAC detection on some hw. This chain can't be used to transmit -++ * or receive frames and it is bounded to a running wdev. -++ * Offchannel radar/CAC detection allows to avoid the CAC downtime -++ * switching to a different channel during CAC detection on the selected -++ * radar channel. -++ * The caller is expected to set chandef pointer to NULL in order to -++ * disable offchannel CAC/radar detection. -+ * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to -+ * resolve a path for hardware flow offloading ++@@ -1719,6 +1719,7 @@ enum ieee80211_offload_flags { ++ * write-protected by sdata_lock and local->mtx so holding either is fine ++ * for read access. ++ * @color_change_color: the bss color that will be used after the change. +++ * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. + */ -+@@ -4267,6 +4275,8 @@ struct ieee80211_ops { -+ struct ieee80211_twt_setup *twt); -+ void (*twt_teardown_request)(struct ieee80211_hw *hw, -+ struct ieee80211_sta *sta, u8 flowid); -++ int (*set_radar_offchan)(struct ieee80211_hw *hw, -++ struct cfg80211_chan_def *chandef); -+ #if LINUX_VERSION_IS_GEQ(5,10,0) -+ int (*net_fill_forward_path)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, ++ struct ieee80211_vif { ++ enum nl80211_iftype type; ++@@ -1750,6 +1751,8 @@ struct ieee80211_vif { ++ bool color_change_active; ++ u8 color_change_color; ++ +++ struct ieee80211_vif *mbssid_tx_vif; +++ ++ /* must be last */ ++ u8 drv_priv[] __aligned(sizeof(void *)); ++ }; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c -+@@ -4344,6 +4344,18 @@ out: -+ return err; ++@@ -112,6 +112,36 @@ static int ieee80211_set_mon_options(str ++ return 0; ++ } ++ +++static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata, +++ struct cfg80211_mbssid_config params) +++{ +++ struct ieee80211_sub_if_data *tx_sdata; +++ +++ sdata->vif.mbssid_tx_vif = NULL; +++ sdata->vif.bss_conf.bssid_index = 0; +++ sdata->vif.bss_conf.nontransmitted = false; +++ sdata->vif.bss_conf.ema_ap = false; +++ +++ if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) +++ return -EINVAL; +++ +++ tx_sdata = IEEE80211_WDEV_TO_SUB_IF(params.tx_wdev); +++ if (!tx_sdata) +++ return -EINVAL; +++ +++ if (tx_sdata == sdata) { +++ sdata->vif.mbssid_tx_vif = &sdata->vif; +++ } else { +++ sdata->vif.mbssid_tx_vif = &tx_sdata->vif; +++ sdata->vif.bss_conf.nontransmitted = true; +++ sdata->vif.bss_conf.bssid_index = params.index; +++ } +++ if (params.ema) +++ sdata->vif.bss_conf.ema_ap = true; +++ +++ return 0; +++} +++ ++ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, ++ const char *name, ++ unsigned char name_assign_type, ++@@ -1107,6 +1137,14 @@ static int ieee80211_start_ap(struct wip ++ changed |= BSS_CHANGED_HE_BSS_COLOR; ++ } ++ +++ if (sdata->vif.type == NL80211_IFTYPE_AP && +++ params->mbssid_config.tx_wdev) { +++ err = ieee80211_set_ap_mbssid_options(sdata, +++ params->mbssid_config); +++ if (err) +++ return err; +++ } +++ ++ mutex_lock(&local->mtx); ++ err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, ++ IEEE80211_CHANCTX_SHARED); ++--- a/net/mac80211/iface.c +++++ b/net/mac80211/iface.c ++@@ -632,17 +632,46 @@ static void ieee80211_do_stop(struct iee ++ ieee80211_add_virtual_monitor(local); + } + -++static int -++ieee80211_set_radar_offchan(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef) +++static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata) ++{ -++ struct ieee80211_local *local = wiphy_priv(wiphy); +++ struct ieee80211_sub_if_data *tx_sdata, *non_tx_sdata, *tmp_sdata; +++ struct ieee80211_vif *tx_vif = sdata->vif.mbssid_tx_vif; ++ -++ if (!local->ops->set_radar_offchan) -++ return -EOPNOTSUPP; +++ if (!tx_vif) +++ return; ++ -++ return local->ops->set_radar_offchan(&local->hw, chandef); +++ tx_sdata = vif_to_sdata(tx_vif); +++ sdata->vif.mbssid_tx_vif = NULL; +++ +++ list_for_each_entry_safe(non_tx_sdata, tmp_sdata, +++ &tx_sdata->local->interfaces, list) { +++ if (non_tx_sdata != sdata && non_tx_sdata != tx_sdata && +++ non_tx_sdata->vif.mbssid_tx_vif == tx_vif && +++ ieee80211_sdata_running(non_tx_sdata)) { +++ non_tx_sdata->vif.mbssid_tx_vif = NULL; +++ dev_close(non_tx_sdata->wdev.netdev); +++ } +++ } +++ +++ if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata)) { +++ tx_sdata->vif.mbssid_tx_vif = NULL; +++ dev_close(tx_sdata->wdev.netdev); +++ } ++} ++ -+ const struct cfg80211_ops mac80211_config_ops = { -+ .add_virtual_intf = ieee80211_add_iface, -+ .del_virtual_intf = ieee80211_del_iface, -+@@ -4448,4 +4460,5 @@ const struct cfg80211_ops mac80211_confi -+ .reset_tid_config = ieee80211_reset_tid_config, -+ .set_sar_specs = ieee80211_set_sar_specs, -+ .color_change = ieee80211_color_change, -++ .set_radar_offchan = ieee80211_set_radar_offchan, -+ }; -diff --git a/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch b/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch ++ static int ieee80211_stop(struct net_device *dev) ++ { ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ ++- /* close all dependent VLAN interfaces before locking wiphy */ +++ /* close dependent VLAN and MBSSID interfaces before locking wiphy */ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) { ++ struct ieee80211_sub_if_data *vlan, *tmpsdata; ++ ++ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, ++ u.vlan.list) ++ dev_close(vlan->dev); +++ +++ ieee80211_stop_mbssid(sdata); ++ } ++ ++ wiphy_lock(sdata->local->hw.wiphy); +diff --git a/package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch new file mode 100644 -index 0000000000..c3a4c0db25 +index 0000000000..fdbcce9450 --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/320-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch -@@ -0,0 +1,532 @@ ++++ b/package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch +@@ -0,0 +1,326 @@ +From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Mon, 29 Nov 2021 14:11:24 +0100 -+Subject: [PATCH] cfg80211: rename offchannel_chain structs to background_chain -+ to avoid confusion with ETSI standard ++Date: Thu, 24 Feb 2022 12:54:58 +0100 ++Subject: [PATCH] mac80211: MBSSID beacon handling in AP mode + -+ETSI standard defines "Offchannel CAC" as: -+"Off-Channel CAC is performed by a number of non-continuous checks -+spread over a period in time. This period, which is required to -+determine the presence of radar signals, is defined as the Off-Channel -+CAC Time.. -+Minimum Off-Channel CAC Time 6 minutes and Maximum Off-Channel CAC Time -+4 hours..". -+mac80211 implementation refers to a dedicated hw chain used for continuous -+radar monitoring. Rename offchannel_* references to background_* in -+order to avoid confusion with ETSI standard. ++Add new fields in struct beacon_data to store all MBSSID elements. ++Generate a beacon template which includes all MBSSID elements. ++Move CSA offset to reflect the MBSSID element length. + ++Co-developed-by: Aloka Dixit <alokad@codeaurora.org> ++Signed-off-by: Aloka Dixit <alokad@codeaurora.org> ++Co-developed-by: John Crispin <john@phrozen.org> ++Signed-off-by: John Crispin <john@phrozen.org> +Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Link: https://lore.kernel.org/r/4204cc1d648d76b44557981713231e030a3bd991.1638190762.git.lorenzo@kernel.org ++Tested-by: Money Wang <money.wang@mediatek.com> ++Link: https://lore.kernel.org/r/5322db3c303f431adaf191ab31c45e151dde5465.1645702516.git.lorenzo@kernel.org ++[small cleanups] +Signed-off-by: Johannes Berg <johannes.berg@intel.com> +--- + -+--- a/include/net/cfg80211.h -++++ b/include/net/cfg80211.h -+@@ -4058,14 +4058,14 @@ struct mgmt_frame_regs { -+ * -+ * @color_change: Initiate a color change. -+ * -+- * @set_radar_offchan: Configure dedicated offchannel chain available for -++ * @set_radar_background: Configure dedicated offchannel chain available for -+ * radar/CAC detection on some hw. This chain can't be used to transmit -+ * or receive frames and it is bounded to a running wdev. -+- * Offchannel radar/CAC detection allows to avoid the CAC downtime -++ * Background radar/CAC detection allows to avoid the CAC downtime -+ * switching to a different channel during CAC detection on the selected -+ * radar channel. -+ * The caller is expected to set chandef pointer to NULL in order to -+- * disable offchannel CAC/radar detection. -++ * disable background CAC/radar detection. -+ */ -+ struct cfg80211_ops { -+ int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -+@@ -4396,8 +4396,8 @@ struct cfg80211_ops { -+ int (*color_change)(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct cfg80211_color_change_settings *params); -+- int (*set_radar_offchan)(struct wiphy *wiphy, -+- struct cfg80211_chan_def *chandef); -++ int (*set_radar_background)(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef); -+ }; -+ -+ /* -+@@ -7601,9 +7601,9 @@ cfg80211_radar_event(struct wiphy *wiphy -+ } -+ -+ static inline void -+-cfg80211_offchan_radar_event(struct wiphy *wiphy, -+- struct cfg80211_chan_def *chandef, -+- gfp_t gfp) -++cfg80211_background_radar_event(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef, -++ gfp_t gfp) -+ { -+ __cfg80211_radar_event(wiphy, chandef, true, gfp); -+ } -+@@ -7638,13 +7638,13 @@ void cfg80211_cac_event(struct net_devic -+ enum nl80211_radar_event event, gfp_t gfp); -+ -+ /** -+- * cfg80211_offchan_cac_abort - Channel Availability Check offchan abort event -++ * cfg80211_background_cac_abort - Channel Availability Check offchan abort event -+ * @wiphy: the wiphy -+ * -+ * This function is called by the driver when a Channel Availability Check -+ * (CAC) is aborted by a offchannel dedicated chain. -+ */ -+-void cfg80211_offchan_cac_abort(struct wiphy *wiphy); -++void cfg80211_background_cac_abort(struct wiphy *wiphy); -+ -+ /** -+ * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h -+@@ -3937,14 +3937,14 @@ struct ieee80211_prep_tx_info { -+ * twt structure. -+ * @twt_teardown_request: Update the hw with TWT teardown request received -+ * from the peer. -+- * @set_radar_offchan: Configure dedicated offchannel chain available for -++ * @set_radar_background: Configure dedicated offchannel chain available for -+ * radar/CAC detection on some hw. This chain can't be used to transmit -+ * or receive frames and it is bounded to a running wdev. -+- * Offchannel radar/CAC detection allows to avoid the CAC downtime -++ * Background radar/CAC detection allows to avoid the CAC downtime -+ * switching to a different channel during CAC detection on the selected -+ * radar channel. -+ * The caller is expected to set chandef pointer to NULL in order to -+- * disable offchannel CAC/radar detection. -++ * disable background CAC/radar detection. -+ * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to -+ * resolve a path for hardware flow offloading -+ */ -+@@ -4275,8 +4275,8 @@ struct ieee80211_ops { -+ struct ieee80211_twt_setup *twt); -+ void (*twt_teardown_request)(struct ieee80211_hw *hw, -+ struct ieee80211_sta *sta, u8 flowid); -+- int (*set_radar_offchan)(struct ieee80211_hw *hw, -+- struct cfg80211_chan_def *chandef); -++ int (*set_radar_background)(struct ieee80211_hw *hw, -++ struct cfg80211_chan_def *chandef); -+ #if LINUX_VERSION_IS_GEQ(5,10,0) -+ int (*net_fill_forward_path)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+--- a/include/uapi/linux/nl80211.h -++++ b/include/uapi/linux/nl80211.h -+@@ -2608,10 +2608,10 @@ enum nl80211_commands { -+ * Mandatory parameter for the transmitting interface to enable MBSSID. -+ * Optional for the non-transmitting interfaces. -+ * -+- * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for -+- * radar/CAC detection on some hw. This chain can't be used to transmit -+- * or receive frames and it is bounded to a running wdev. -+- * Offchannel radar/CAC detection allows to avoid the CAC downtime -++ * @NL80211_ATTR_RADAR_BACKGROUND: Configure dedicated offchannel chain -++ * available for radar/CAC detection on some hw. This chain can't be used -++ * to transmit or receive frames and it is bounded to a running wdev. -++ * Background radar/CAC detection allows to avoid the CAC downtime -+ * switching on a different channel during CAC detection on the selected -+ * radar channel. -+ * -+@@ -3121,7 +3121,7 @@ enum nl80211_attrs { -+ NL80211_ATTR_MBSSID_CONFIG, -+ NL80211_ATTR_MBSSID_ELEMS, -+ -+- NL80211_ATTR_RADAR_OFFCHAN, -++ NL80211_ATTR_RADAR_BACKGROUND, -+ -+ /* add attributes here, update the policy in nl80211.c */ -+ -+@@ -6022,7 +6022,7 @@ enum nl80211_feature_flags { -+ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision -+ * detection and change announcemnts. -+ * -+- * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC -++ * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC -+ * detection. -+ * -+ * @NUM_NL80211_EXT_FEATURES: number of extended features. -+@@ -6090,7 +6090,7 @@ enum nl80211_ext_feature_index { -+ NL80211_EXT_FEATURE_SECURE_RTT, -+ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, -+ NL80211_EXT_FEATURE_BSS_COLOR, -+- NL80211_EXT_FEATURE_RADAR_OFFCHAN, -++ NL80211_EXT_FEATURE_RADAR_BACKGROUND, ++@@ -4938,12 +4938,14 @@ void ieee80211_report_low_ack(struct iee ++ * @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets ++ * to countdown counters. This array can contain zero values which ++ * should be ignored. +++ * @mbssid_off: position of the multiple bssid element ++ */ ++ struct ieee80211_mutable_offsets { ++ u16 tim_offset; ++ u16 tim_length; + -+ /* add new features before the definition below */ -+ NUM_NL80211_EXT_FEATURES, ++ u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; +++ u16 mbssid_off; ++ }; ++ ++ /** +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c -+@@ -4345,15 +4345,15 @@ out: ++@@ -989,11 +989,29 @@ static int ieee80211_set_ftm_responder_p ++ return 0; + } + -+ static int -+-ieee80211_set_radar_offchan(struct wiphy *wiphy, -+- struct cfg80211_chan_def *chandef) -++ieee80211_set_radar_background(struct wiphy *wiphy, -++ struct cfg80211_chan_def *chandef) +++static int +++ieee80211_copy_mbssid_beacon(u8 *pos, struct cfg80211_mbssid_elems *dst, +++ struct cfg80211_mbssid_elems *src) +++{ +++ int i, offset = 0; +++ +++ for (i = 0; i < src->cnt; i++) { +++ memcpy(pos + offset, src->elem[i].data, src->elem[i].len); +++ dst->elem[i].len = src->elem[i].len; +++ dst->elem[i].data = pos + offset; +++ offset += dst->elem[i].len; +++ } +++ dst->cnt = src->cnt; +++ +++ return offset; +++} +++ ++ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, ++ struct cfg80211_beacon_data *params, ++ const struct ieee80211_csa_settings *csa, ++ const struct ieee80211_color_change_settings *cca) + { -+ struct ieee80211_local *local = wiphy_priv(wiphy); +++ struct cfg80211_mbssid_elems *mbssid = NULL; ++ struct beacon_data *new, *old; ++ int new_head_len, new_tail_len; ++ int size, err; ++@@ -1021,6 +1039,17 @@ static int ieee80211_assign_beacon(struc + -+- if (!local->ops->set_radar_offchan) -++ if (!local->ops->set_radar_background) -+ return -EOPNOTSUPP; ++ size = sizeof(*new) + new_head_len + new_tail_len; + -+- return local->ops->set_radar_offchan(&local->hw, chandef); -++ return local->ops->set_radar_background(&local->hw, chandef); -+ } +++ /* new or old multiple BSSID elements? */ +++ if (params->mbssid_ies) { +++ mbssid = params->mbssid_ies; +++ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); +++ size += ieee80211_get_mbssid_beacon_len(mbssid); +++ } else if (old && old->mbssid_ies) { +++ mbssid = old->mbssid_ies; +++ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); +++ size += ieee80211_get_mbssid_beacon_len(mbssid); +++ } +++ ++ new = kzalloc(size, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; ++@@ -1029,12 +1058,20 @@ static int ieee80211_assign_beacon(struc + -+ const struct cfg80211_ops mac80211_config_ops = { -+@@ -4460,5 +4460,5 @@ const struct cfg80211_ops mac80211_confi -+ .reset_tid_config = ieee80211_reset_tid_config, -+ .set_sar_specs = ieee80211_set_sar_specs, -+ .color_change = ieee80211_color_change, -+- .set_radar_offchan = ieee80211_set_radar_offchan, -++ .set_radar_background = ieee80211_set_radar_background, -+ }; -+--- a/net/wireless/chan.c -++++ b/net/wireless/chan.c -+@@ -716,13 +716,13 @@ static bool -+ cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, -+ struct ieee80211_channel *channel) -+ { -+- if (!rdev->offchan_radar_wdev) -++ if (!rdev->background_radar_wdev) -+ return false; ++ /* ++ * pointers go into the block we allocated, ++- * memory is | beacon_data | head | tail | +++ * memory is | beacon_data | head | tail | mbssid_ies ++ */ ++ new->head = ((u8 *) new) + sizeof(*new); ++ new->tail = new->head + new_head_len; ++ new->head_len = new_head_len; ++ new->tail_len = new_tail_len; +++ /* copy in optional mbssid_ies */ +++ if (mbssid) { +++ u8 *pos = new->tail + new->tail_len; +++ +++ new->mbssid_ies = (void *)pos; +++ pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); +++ ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid); +++ } + -+- if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) -++ if (!cfg80211_chandef_valid(&rdev->background_radar_chandef)) -+ return false; ++ if (csa) { ++ new->cntdwn_current_counter = csa->count; ++@@ -1332,8 +1369,11 @@ static int ieee80211_stop_ap(struct wiph + -+- return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); -++ return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel); -+ } ++ mutex_unlock(&local->mtx); + -+ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, -+--- a/net/wireless/core.c -++++ b/net/wireless/core.c -+@@ -543,9 +543,10 @@ use_default_name: -+ INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); -+ INIT_WORK(&rdev->conn_work, cfg80211_conn_work); -+ INIT_WORK(&rdev->event_work, cfg80211_event_work); -+- INIT_WORK(&rdev->offchan_cac_abort_wk, cfg80211_offchan_cac_abort_wk); -+- INIT_DELAYED_WORK(&rdev->offchan_cac_done_wk, -+- cfg80211_offchan_cac_done_wk); -++ INIT_WORK(&rdev->background_cac_abort_wk, -++ cfg80211_background_cac_abort_wk); -++ INIT_DELAYED_WORK(&rdev->background_cac_done_wk, -++ cfg80211_background_cac_done_wk); ++- kfree(sdata->u.ap.next_beacon); ++- sdata->u.ap.next_beacon = NULL; +++ if (sdata->u.ap.next_beacon) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); +++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; +++ } + -+ init_waitqueue_head(&rdev->dev_wait); ++ /* turn off carrier for this interface and dependent VLANs */ ++ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) ++@@ -3126,12 +3166,24 @@ cfg80211_beacon_dup(struct cfg80211_beac + -+@@ -1055,13 +1056,13 @@ void wiphy_unregister(struct wiphy *wiph -+ cancel_work_sync(&rdev->conn_work); -+ flush_work(&rdev->event_work); -+ cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); -+- cancel_delayed_work_sync(&rdev->offchan_cac_done_wk); -++ cancel_delayed_work_sync(&rdev->background_cac_done_wk); -+ flush_work(&rdev->destroy_work); -+ flush_work(&rdev->sched_scan_stop_wk); -+ flush_work(&rdev->propagate_radar_detect_wk); -+ flush_work(&rdev->propagate_cac_done_wk); -+ flush_work(&rdev->mgmt_registrations_update_wk); -+- flush_work(&rdev->offchan_cac_abort_wk); -++ flush_work(&rdev->background_cac_abort_wk); ++ len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + ++ beacon->proberesp_ies_len + beacon->assocresp_ies_len + ++- beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len; +++ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len + +++ ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); + -+ #ifdef CONFIG_PM -+ if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) -+@@ -1210,7 +1211,7 @@ void __cfg80211_leave(struct cfg80211_re ++ new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); ++ if (!new_beacon) ++ return NULL; + -+ cfg80211_pmsr_wdev_down(wdev); +++ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { +++ new_beacon->mbssid_ies = +++ kzalloc(struct_size(new_beacon->mbssid_ies, +++ elem, beacon->mbssid_ies->cnt), +++ GFP_KERNEL); +++ if (!new_beacon->mbssid_ies) { +++ kfree(new_beacon); +++ return NULL; +++ } +++ } +++ ++ pos = (u8 *)(new_beacon + 1); ++ if (beacon->head_len) { ++ new_beacon->head_len = beacon->head_len; ++@@ -3169,6 +3221,10 @@ cfg80211_beacon_dup(struct cfg80211_beac ++ memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); ++ pos += beacon->probe_resp_len; ++ } +++ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) +++ pos += ieee80211_copy_mbssid_beacon(pos, +++ new_beacon->mbssid_ies, +++ beacon->mbssid_ies); + -+- cfg80211_stop_offchan_radar_detection(wdev); -++ cfg80211_stop_background_radar_detection(wdev); ++ /* might copy -1, meaning no changes requested */ ++ new_beacon->ftm_responder = beacon->ftm_responder; ++@@ -3206,8 +3262,11 @@ static int ieee80211_set_after_csa_beaco ++ case NL80211_IFTYPE_AP: ++ err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, ++ NULL, NULL); ++- kfree(sdata->u.ap.next_beacon); ++- sdata->u.ap.next_beacon = NULL; +++ if (sdata->u.ap.next_beacon) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); +++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; +++ } + -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_ADHOC: -+--- a/net/wireless/core.h -++++ b/net/wireless/core.h -+@@ -84,10 +84,10 @@ struct cfg80211_registered_device { ++ if (err < 0) ++ return err; ++@@ -3362,8 +3421,12 @@ static int ieee80211_set_csa_beacon(stru ++ if ((params->n_counter_offsets_beacon > ++ IEEE80211_MAX_CNTDWN_COUNTERS_NUM) || ++ (params->n_counter_offsets_presp > ++- IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) +++ IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); +++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; ++ return -EINVAL; +++ } ++ ++ csa.counter_offsets_beacon = params->counter_offsets_beacon; ++ csa.counter_offsets_presp = params->counter_offsets_presp; ++@@ -3373,7 +3436,9 @@ static int ieee80211_set_csa_beacon(stru ++ ++ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa, NULL); ++ if (err < 0) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); ++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; ++ return err; ++ } ++ *changed |= err; ++@@ -3463,8 +3528,11 @@ static int ieee80211_set_csa_beacon(stru ++ static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata) ++ { ++ sdata->vif.color_change_active = false; ++- kfree(sdata->u.ap.next_beacon); ++- sdata->u.ap.next_beacon = NULL; +++ if (sdata->u.ap.next_beacon) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); +++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; +++ } ++ ++ cfg80211_color_change_aborted_notify(sdata->dev); ++ } ++@@ -4202,8 +4270,11 @@ ieee80211_set_after_color_change_beacon( ++ ++ ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, ++ NULL, NULL); ++- kfree(sdata->u.ap.next_beacon); ++- sdata->u.ap.next_beacon = NULL; +++ if (sdata->u.ap.next_beacon) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); +++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; +++ } + -+ struct delayed_work dfs_update_channels_wk; ++ if (ret < 0) ++ return ret; ++@@ -4246,7 +4317,11 @@ ieee80211_set_color_change_beacon(struct ++ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_color_change, ++ NULL, &color_change); ++ if (err < 0) { ++- kfree(sdata->u.ap.next_beacon); +++ if (sdata->u.ap.next_beacon) { +++ kfree(sdata->u.ap.next_beacon->mbssid_ies); +++ kfree(sdata->u.ap.next_beacon); +++ sdata->u.ap.next_beacon = NULL; +++ } ++ return err; ++ } ++ *changed |= err; ++--- a/net/mac80211/ieee80211_i.h +++++ b/net/mac80211/ieee80211_i.h ++@@ -261,6 +261,7 @@ struct beacon_data { ++ struct ieee80211_meshconf_ie *meshconf; ++ u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; ++ u8 cntdwn_current_counter; +++ struct cfg80211_mbssid_elems *mbssid_ies; ++ struct rcu_head rcu_head; ++ }; + -+- struct wireless_dev *offchan_radar_wdev; -+- struct cfg80211_chan_def offchan_radar_chandef; -+- struct delayed_work offchan_cac_done_wk; -+- struct work_struct offchan_cac_abort_wk; -++ struct wireless_dev *background_radar_wdev; -++ struct cfg80211_chan_def background_radar_chandef; -++ struct delayed_work background_cac_done_wk; -++ struct work_struct background_cac_abort_wk; ++@@ -1083,6 +1084,20 @@ ieee80211_vif_get_shift(struct ieee80211 ++ return shift; ++ } + -+ /* netlink port which started critical protocol (0 means not started) */ -+ u32 crit_proto_nlportid; -+@@ -497,15 +497,15 @@ cfg80211_chandef_dfs_cac_time(struct wip -+ void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); +++static inline int +++ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems) +++{ +++ int i, len = 0; +++ +++ if (!elems) +++ return 0; +++ +++ for (i = 0; i < elems->cnt; i++) +++ len += elems->elem[i].len; +++ +++ return len; +++} +++ ++ enum { ++ IEEE80211_RX_MSG = 1, ++ IEEE80211_TX_STATUS_MSG = 2, ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -5041,6 +5041,19 @@ ieee80211_beacon_get_finish(struct ieee8 ++ IEEE80211_TX_CTL_FIRST_FRAGMENT; ++ } + -+ int -+-cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -+- struct wireless_dev *wdev, -+- struct cfg80211_chan_def *chandef); -++cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, -++ struct wireless_dev *wdev, -++ struct cfg80211_chan_def *chandef); +++static void +++ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon) +++{ +++ int i; +++ +++ if (!beacon->mbssid_ies) +++ return; +++ +++ for (i = 0; i < beacon->mbssid_ies->cnt; i++) +++ skb_put_data(skb, beacon->mbssid_ies->elem[i].data, +++ beacon->mbssid_ies->elem[i].len); +++} +++ ++ static struct sk_buff * ++ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++@@ -5054,6 +5067,7 @@ ieee80211_beacon_get_ap(struct ieee80211 ++ struct ieee80211_if_ap *ap = &sdata->u.ap; ++ struct sk_buff *skb = NULL; ++ u16 csa_off_base = 0; +++ int mbssid_len; + -+-void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); -++void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); ++ if (beacon->cntdwn_counter_offsets[0]) { ++ if (!is_template) ++@@ -5063,11 +5077,12 @@ ieee80211_beacon_get_ap(struct ieee80211 ++ } + -+-void cfg80211_offchan_cac_done_wk(struct work_struct *work); -++void cfg80211_background_cac_done_wk(struct work_struct *work); ++ /* headroom, head length, ++- * tail length and maximum TIM length +++ * tail length, maximum TIM length and multiple BSSID length ++ */ +++ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); ++ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + ++ beacon->tail_len + 256 + ++- local->hw.extra_beacon_tailroom); +++ local->hw.extra_beacon_tailroom + mbssid_len); ++ if (!skb) ++ return NULL; + -+-void cfg80211_offchan_cac_abort_wk(struct work_struct *work); -++void cfg80211_background_cac_abort_wk(struct work_struct *work); ++@@ -5081,6 +5096,11 @@ ieee80211_beacon_get_ap(struct ieee80211 ++ offs->tim_length = skb->len - beacon->head_len; ++ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; + -+ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, -+ struct ieee80211_channel *chan); -+--- a/net/wireless/mlme.c -++++ b/net/wireless/mlme.c -+@@ -920,7 +920,7 @@ void __cfg80211_radar_event(struct wiphy -+ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); +++ if (mbssid_len) { +++ ieee80211_beacon_add_mbssid(skb, beacon); +++ offs->mbssid_off = skb->len - mbssid_len; +++ } +++ ++ /* for AP the csa offsets are from tail */ ++ csa_off_base = skb->len; ++ } +diff --git a/package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch b/package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch +new file mode 100644 +index 0000000000..38b0de180e +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch +@@ -0,0 +1,52 @@ ++From: John Crispin <john@phrozen.org> ++Date: Thu, 24 Feb 2022 12:54:59 +0100 ++Subject: [PATCH] mac80211: MBSSID channel switch ++ ++Trigger ieee80211_csa_finish() on the non-transmitting interfaces ++when channel switch concludes on the transmitting interface. ++ ++Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Co-developed-by: Aloka Dixit <alokad@codeaurora.org> ++Signed-off-by: Aloka Dixit <alokad@codeaurora.org> ++Signed-off-by: John Crispin <john@phrozen.org> ++Link: https://lore.kernel.org/r/6fde4d7f9fa387494f46a7aa4a584478dcda06f1.1645702516.git.lorenzo@kernel.org ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++--- ++ ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -3247,9 +3247,31 @@ cfg80211_beacon_dup(struct cfg80211_beac ++ void ieee80211_csa_finish(struct ieee80211_vif *vif) ++ { ++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); +++ struct ieee80211_local *local = sdata->local; + -+ if (offchan) -+- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); -++ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); ++- ieee80211_queue_work(&sdata->local->hw, ++- &sdata->csa_finalize_work); +++ rcu_read_lock(); +++ +++ if (vif->mbssid_tx_vif == vif) { +++ /* Trigger ieee80211_csa_finish() on the non-transmitting +++ * interfaces when channel switch is received on +++ * transmitting interface +++ */ +++ struct ieee80211_sub_if_data *iter; +++ +++ list_for_each_entry_rcu(iter, &local->interfaces, list) { +++ if (!ieee80211_sdata_running(iter)) +++ continue; +++ +++ if (iter == sdata || iter->vif.mbssid_tx_vif != vif) +++ continue; +++ +++ ieee80211_queue_work(&iter->local->hw, +++ &iter->csa_finalize_work); +++ } +++ } +++ ieee80211_queue_work(&local->hw, &sdata->csa_finalize_work); +++ +++ rcu_read_unlock(); ++ } ++ EXPORT_SYMBOL(ieee80211_csa_finish); + -+ cfg80211_sched_dfs_chan_update(rdev); +diff --git a/package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch b/package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch +new file mode 100644 +index 0000000000..1955568607 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch +@@ -0,0 +1,25 @@ ++From: Lorenzo Bianconi <lorenzo@kernel.org> ++Date: Thu, 24 Feb 2022 12:55:00 +0100 ++Subject: [PATCH] mac80211: update bssid_indicator in ++ ieee80211_assign_beacon ++ ++Update bssid_indicator in ieee80211_bss_conf according to the ++number of bssid in the set. ++ ++Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Link: https://lore.kernel.org/r/f92317e002fca9933f05a445fcefb4f53291d601.1645702516.git.lorenzo@kernel.org ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++--- ++ ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -1071,6 +1071,9 @@ static int ieee80211_assign_beacon(struc ++ new->mbssid_ies = (void *)pos; ++ pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); ++ ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid); +++ /* update bssid_indicator */ +++ sdata->vif.bss_conf.bssid_indicator = +++ ilog2(__roundup_pow_of_two(mbssid->cnt + 1)); ++ } + -+@@ -975,10 +975,10 @@ void cfg80211_cac_event(struct net_devic -+ EXPORT_SYMBOL(cfg80211_cac_event); ++ if (csa) { +diff --git a/package/kernel/mac80211/patches/subsys/328-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch b/package/kernel/mac80211/patches/subsys/328-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch +new file mode 100644 +index 0000000000..f0150ddef0 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/328-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch +@@ -0,0 +1,38 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Sat, 26 Mar 2022 23:58:35 +0100 ++Subject: [PATCH] mac80211: do not wake queues on a vif that is being stopped ++ ++When a vif is being removed and sdata->bss is cleared, __ieee80211_wake_txqs ++can still be called on it, which crashes as soon as sdata->bss is being ++dereferenced. ++To fix this properly, check for SDATA_STATE_RUNNING before waking queues, ++and take the fq lock when setting it (to ensure that __ieee80211_wake_txqs ++observes the change when running on a different CPU ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/iface.c +++++ b/net/mac80211/iface.c ++@@ -377,7 +377,9 @@ static void ieee80211_do_stop(struct iee ++ bool cancel_scan; ++ struct cfg80211_nan_func *func; ++ +++ spin_lock_bh(&local->fq.lock); ++ clear_bit(SDATA_STATE_RUNNING, &sdata->state); +++ spin_unlock_bh(&local->fq.lock); ++ ++ cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; ++ if (cancel_scan) ++--- a/net/mac80211/util.c +++++ b/net/mac80211/util.c ++@@ -301,6 +301,9 @@ static void __ieee80211_wake_txqs(struct ++ local_bh_disable(); ++ spin_lock(&fq->lock); ++ +++ if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) +++ goto out; +++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) ++ ps = &sdata->bss->ps; + -+ static void -+-__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, -+- struct wireless_dev *wdev, -+- const struct cfg80211_chan_def *chandef, -+- enum nl80211_radar_event event) -++__cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, -++ struct wireless_dev *wdev, -++ const struct cfg80211_chan_def *chandef, -++ enum nl80211_radar_event event) -+ { -+ struct wiphy *wiphy = &rdev->wiphy; -+ struct net_device *netdev; -+@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 -+ if (!cfg80211_chandef_valid(chandef)) -+ return; +diff --git a/package/kernel/mac80211/patches/subsys/330-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch b/package/kernel/mac80211/patches/subsys/330-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch +new file mode 100644 +index 0000000000..0ca53860a5 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/330-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch +@@ -0,0 +1,1249 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Sun, 19 Jun 2022 23:13:05 +0200 ++Subject: [PATCH] mac80211: switch airtime fairness back to deficit round-robin ++ scheduling ++ ++This reverts commits 6a789ba679d652587532cec2a0e0274fda172f3b and ++2433647bc8d983a543e7d31b41ca2de1c7e2c198. ++ ++The virtual time scheduler code has a number of issues: ++- queues slowed down by hardware/firmware powersave handling were not properly ++ handled. ++- on ath10k in push-pull mode, tx queues that the driver tries to pull from ++ were starved, causing excessive latency ++- delay between tx enqueue and reported airtime use were causing excessively ++ bursty tx behavior ++ ++The bursty behavior may also be present on the round-robin scheduler, but there ++it is much easier to fix without introducing additional regressions ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/include/net/mac80211.h +++++ b/include/net/mac80211.h ++@@ -6666,6 +6666,9 @@ static inline void ieee80211_txq_schedul ++ { ++ } + -+- if (!rdev->offchan_radar_wdev) -++ if (!rdev->background_radar_wdev) -+ return; +++void __ieee80211_schedule_txq(struct ieee80211_hw *hw, +++ struct ieee80211_txq *txq, bool force); +++ ++ /** ++ * ieee80211_schedule_txq - schedule a TXQ for transmission ++ * ++@@ -6678,7 +6681,11 @@ static inline void ieee80211_txq_schedul ++ * The driver may call this function if it has buffered packets for ++ * this TXQ internally. ++ */ ++-void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); +++static inline void +++ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) +++{ +++ __ieee80211_schedule_txq(hw, txq, true); +++} + -+ switch (event) { -+@@ -997,12 +997,12 @@ __cfg80211_offchan_cac_event(struct cfg8 -+ memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef)); -+ queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); -+ cfg80211_sched_dfs_chan_update(rdev); -+- wdev = rdev->offchan_radar_wdev; -++ wdev = rdev->background_radar_wdev; -+ break; -+ case NL80211_RADAR_CAC_ABORTED: -+- if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) -++ if (!cancel_delayed_work(&rdev->background_cac_done_wk)) -+ return; -+- wdev = rdev->offchan_radar_wdev; -++ wdev = rdev->background_radar_wdev; -+ break; -+ case NL80211_RADAR_CAC_STARTED: -+ break; -+@@ -1015,49 +1015,49 @@ __cfg80211_offchan_cac_event(struct cfg8 ++ /** ++ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() ++@@ -6690,8 +6697,12 @@ void ieee80211_schedule_txq(struct ieee8 ++ * The driver may set force=true if it has buffered packets for this TXQ ++ * internally. ++ */ ++-void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, ++- bool force); +++static inline void +++ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, +++ bool force) +++{ +++ __ieee80211_schedule_txq(hw, txq, force); +++} ++ ++ /** ++ * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit ++--- a/net/mac80211/cfg.c +++++ b/net/mac80211/cfg.c ++@@ -1554,38 +1554,6 @@ static void sta_apply_mesh_params(struct ++ #endif + } + -+ static void -+-cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, -+- const struct cfg80211_chan_def *chandef, -+- enum nl80211_radar_event event) -++cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, -++ const struct cfg80211_chan_def *chandef, -++ enum nl80211_radar_event event) -+ { -+ wiphy_lock(&rdev->wiphy); -+- __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, -+- chandef, event); -++ __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev, -++ chandef, event); -+ wiphy_unlock(&rdev->wiphy); ++-static void sta_apply_airtime_params(struct ieee80211_local *local, ++- struct sta_info *sta, ++- struct station_parameters *params) ++-{ ++- u8 ac; ++- ++- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++- struct airtime_sched_info *air_sched = &local->airtime[ac]; ++- struct airtime_info *air_info = &sta->airtime[ac]; ++- struct txq_info *txqi; ++- u8 tid; ++- ++- spin_lock_bh(&air_sched->lock); ++- for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { ++- if (air_info->weight == params->airtime_weight || ++- !sta->sta.txq[tid] || ++- ac != ieee80211_ac_from_tid(tid)) ++- continue; ++- ++- airtime_weight_set(air_info, params->airtime_weight); ++- ++- txqi = to_txq_info(sta->sta.txq[tid]); ++- if (RB_EMPTY_NODE(&txqi->schedule_order)) ++- continue; ++- ++- ieee80211_update_airtime_weight(local, air_sched, ++- 0, true); ++- } ++- spin_unlock_bh(&air_sched->lock); ++- } ++-} ++- ++ static int sta_apply_parameters(struct ieee80211_local *local, ++ struct sta_info *sta, ++ struct station_parameters *params) ++@@ -1773,8 +1741,7 @@ static int sta_apply_parameters(struct i ++ sta_apply_mesh_params(local, sta, params); ++ ++ if (params->airtime_weight) ++- sta_apply_airtime_params(local, sta, params); ++- +++ sta->airtime_weight = params->airtime_weight; ++ ++ /* set the STA state after all sta info from usermode has been set */ ++ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || ++--- a/net/mac80211/debugfs.c +++++ b/net/mac80211/debugfs.c ++@@ -216,14 +216,14 @@ static ssize_t aql_txq_limit_read(struct ++ "VI %u %u\n" ++ "BE %u %u\n" ++ "BK %u %u\n", ++- local->airtime[IEEE80211_AC_VO].aql_txq_limit_low, ++- local->airtime[IEEE80211_AC_VO].aql_txq_limit_high, ++- local->airtime[IEEE80211_AC_VI].aql_txq_limit_low, ++- local->airtime[IEEE80211_AC_VI].aql_txq_limit_high, ++- local->airtime[IEEE80211_AC_BE].aql_txq_limit_low, ++- local->airtime[IEEE80211_AC_BE].aql_txq_limit_high, ++- local->airtime[IEEE80211_AC_BK].aql_txq_limit_low, ++- local->airtime[IEEE80211_AC_BK].aql_txq_limit_high); +++ local->aql_txq_limit_low[IEEE80211_AC_VO], +++ local->aql_txq_limit_high[IEEE80211_AC_VO], +++ local->aql_txq_limit_low[IEEE80211_AC_VI], +++ local->aql_txq_limit_high[IEEE80211_AC_VI], +++ local->aql_txq_limit_low[IEEE80211_AC_BE], +++ local->aql_txq_limit_high[IEEE80211_AC_BE], +++ local->aql_txq_limit_low[IEEE80211_AC_BK], +++ local->aql_txq_limit_high[IEEE80211_AC_BK]); ++ return simple_read_from_buffer(user_buf, count, ppos, ++ buf, len); + } ++@@ -255,11 +255,11 @@ static ssize_t aql_txq_limit_write(struc ++ if (ac >= IEEE80211_NUM_ACS) ++ return -EINVAL; + -+-void cfg80211_offchan_cac_done_wk(struct work_struct *work) -++void cfg80211_background_cac_done_wk(struct work_struct *work) -+ { -+ struct delayed_work *delayed_work = to_delayed_work(work); -+ struct cfg80211_registered_device *rdev; ++- q_limit_low_old = local->airtime[ac].aql_txq_limit_low; ++- q_limit_high_old = local->airtime[ac].aql_txq_limit_high; +++ q_limit_low_old = local->aql_txq_limit_low[ac]; +++ q_limit_high_old = local->aql_txq_limit_high[ac]; + -+ rdev = container_of(delayed_work, struct cfg80211_registered_device, -+- offchan_cac_done_wk); -+- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, -+- NL80211_RADAR_CAC_FINISHED); -++ background_cac_done_wk); -++ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, -++ NL80211_RADAR_CAC_FINISHED); -+ } ++- local->airtime[ac].aql_txq_limit_low = q_limit_low; ++- local->airtime[ac].aql_txq_limit_high = q_limit_high; +++ local->aql_txq_limit_low[ac] = q_limit_low; +++ local->aql_txq_limit_high[ac] = q_limit_high; + -+-void cfg80211_offchan_cac_abort_wk(struct work_struct *work) -++void cfg80211_background_cac_abort_wk(struct work_struct *work) -+ { -+ struct cfg80211_registered_device *rdev; ++ mutex_lock(&local->sta_mtx); ++ list_for_each_entry(sta, &local->sta_list, list) { ++@@ -382,46 +382,6 @@ static const struct file_operations forc ++ .llseek = default_llseek, ++ }; + -+ rdev = container_of(work, struct cfg80211_registered_device, -+- offchan_cac_abort_wk); -+- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, -+- NL80211_RADAR_CAC_ABORTED); -++ background_cac_abort_wk); -++ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, -++ NL80211_RADAR_CAC_ABORTED); ++-static ssize_t airtime_read(struct file *file, ++- char __user *user_buf, ++- size_t count, ++- loff_t *ppos) ++-{ ++- struct ieee80211_local *local = file->private_data; ++- char buf[200]; ++- u64 v_t[IEEE80211_NUM_ACS]; ++- u64 wt[IEEE80211_NUM_ACS]; ++- int len = 0, ac; ++- ++- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++- spin_lock_bh(&local->airtime[ac].lock); ++- v_t[ac] = local->airtime[ac].v_t; ++- wt[ac] = local->airtime[ac].weight_sum; ++- spin_unlock_bh(&local->airtime[ac].lock); ++- } ++- len = scnprintf(buf, sizeof(buf), ++- "\tVO VI BE BK\n" ++- "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n" ++- "Weight\t%-10llu %-10llu %-10llu %-10llu\n", ++- v_t[0], ++- v_t[1], ++- v_t[2], ++- v_t[3], ++- wt[0], ++- wt[1], ++- wt[2], ++- wt[3]); ++- ++- return simple_read_from_buffer(user_buf, count, ppos, ++- buf, len); ++-} ++- ++-static const struct file_operations airtime_ops = { ++- .read = airtime_read, ++- .open = simple_open, ++- .llseek = default_llseek, ++-}; ++- ++ #ifdef CONFIG_PM ++ static ssize_t reset_write(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++@@ -672,11 +632,7 @@ void debugfs_hw_add(struct ieee80211_loc ++ if (local->ops->wake_tx_queue) ++ DEBUGFS_ADD_MODE(aqm, 0600); ++ ++- if (wiphy_ext_feature_isset(local->hw.wiphy, ++- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { ++- DEBUGFS_ADD_MODE(airtime, 0600); ++- DEBUGFS_ADD_MODE(airtime_flags, 0600); ++- } +++ DEBUGFS_ADD_MODE(airtime_flags, 0600); ++ ++ DEBUGFS_ADD(aql_txq_limit); ++ debugfs_create_u32("aql_threshold", 0600, ++--- a/net/mac80211/debugfs_netdev.c +++++ b/net/mac80211/debugfs_netdev.c ++@@ -512,34 +512,6 @@ static ssize_t ieee80211_if_fmt_aqm( + } ++ IEEE80211_IF_FILE_R(aqm); + -+-void cfg80211_offchan_cac_abort(struct wiphy *wiphy) -++void cfg80211_background_cac_abort(struct wiphy *wiphy) -+ { -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++-static ssize_t ieee80211_if_fmt_airtime( ++- const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) ++-{ ++- struct ieee80211_local *local = sdata->local; ++- struct ieee80211_txq *txq = sdata->vif.txq; ++- struct airtime_info *air_info; ++- int len; ++- ++- if (!txq) ++- return 0; ++- ++- spin_lock_bh(&local->airtime[txq->ac].lock); ++- air_info = to_airtime_info(txq); ++- len = scnprintf(buf, ++- buflen, ++- "RX: %llu us\nTX: %llu us\nWeight: %u\n" ++- "Virt-T: %lld us\n", ++- air_info->rx_airtime, ++- air_info->tx_airtime, ++- air_info->weight, ++- air_info->v_t); ++- spin_unlock_bh(&local->airtime[txq->ac].lock); ++- ++- return len; ++-} ++- ++-IEEE80211_IF_FILE_R(airtime); ++- ++ IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX); + -+- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); -++ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); ++ /* IBSS attributes */ ++@@ -685,10 +657,8 @@ static void add_common_files(struct ieee ++ ++ if (sdata->local->ops->wake_tx_queue && ++ sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && ++- sdata->vif.type != NL80211_IFTYPE_NAN) { +++ sdata->vif.type != NL80211_IFTYPE_NAN) ++ DEBUGFS_ADD(aqm); ++- DEBUGFS_ADD(airtime); ++- } + } -+-EXPORT_SYMBOL(cfg80211_offchan_cac_abort); -++EXPORT_SYMBOL(cfg80211_background_cac_abort); + -+ int -+-cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -+- struct wireless_dev *wdev, -+- struct cfg80211_chan_def *chandef) -++cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, -++ struct wireless_dev *wdev, -++ struct cfg80211_chan_def *chandef) -+ { -+ unsigned int cac_time_ms; -+ int err; -+@@ -1065,19 +1065,19 @@ cfg80211_start_offchan_radar_detection(s -+ lockdep_assert_wiphy(&rdev->wiphy); ++ static void add_sta_files(struct ieee80211_sub_if_data *sdata) ++--- a/net/mac80211/debugfs_sta.c +++++ b/net/mac80211/debugfs_sta.c ++@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f ++ size_t bufsz = 400; ++ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; ++ u64 rx_airtime = 0, tx_airtime = 0; ++- u64 v_t[IEEE80211_NUM_ACS]; +++ s64 deficit[IEEE80211_NUM_ACS]; ++ ssize_t rv; ++ int ac; ++ ++@@ -210,18 +210,18 @@ static ssize_t sta_airtime_read(struct f ++ return -ENOMEM; + -+ if (!wiphy_ext_feature_isset(&rdev->wiphy, -+- NL80211_EXT_FEATURE_RADAR_OFFCHAN)) -++ NL80211_EXT_FEATURE_RADAR_BACKGROUND)) -+ return -EOPNOTSUPP; ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++- spin_lock_bh(&local->airtime[ac].lock); +++ spin_lock_bh(&local->active_txq_lock[ac]); ++ rx_airtime += sta->airtime[ac].rx_airtime; ++ tx_airtime += sta->airtime[ac].tx_airtime; ++- v_t[ac] = sta->airtime[ac].v_t; ++- spin_unlock_bh(&local->airtime[ac].lock); +++ deficit[ac] = sta->airtime[ac].deficit; +++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } + -+ /* Offchannel chain already locked by another wdev */ -+- if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) -++ if (rdev->background_radar_wdev && rdev->background_radar_wdev != wdev) -+ return -EBUSY; ++ p += scnprintf(p, bufsz + buf - p, ++ "RX: %llu us\nTX: %llu us\nWeight: %u\n" ++- "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", ++- rx_airtime, tx_airtime, sta->airtime[0].weight, ++- v_t[0], v_t[1], v_t[2], v_t[3]); +++ "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", +++ rx_airtime, tx_airtime, sta->airtime_weight, +++ deficit[0], deficit[1], deficit[2], deficit[3]); ++ ++ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); ++ kfree(buf); ++@@ -236,11 +236,11 @@ static ssize_t sta_airtime_write(struct ++ int ac; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++- spin_lock_bh(&local->airtime[ac].lock); +++ spin_lock_bh(&local->active_txq_lock[ac]); ++ sta->airtime[ac].rx_airtime = 0; ++ sta->airtime[ac].tx_airtime = 0; ++- sta->airtime[ac].v_t = 0; ++- spin_unlock_bh(&local->airtime[ac].lock); +++ sta->airtime[ac].deficit = sta->airtime_weight; +++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } + -+ /* CAC already in progress on the offchannel chain */ -+- if (rdev->offchan_radar_wdev == wdev && -+- delayed_work_pending(&rdev->offchan_cac_done_wk)) -++ if (rdev->background_radar_wdev == wdev && -++ delayed_work_pending(&rdev->background_cac_done_wk)) -+ return -EBUSY; ++ return count; ++@@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file ++ return -ENOMEM; + -+- err = rdev_set_radar_offchan(rdev, chandef); -++ err = rdev_set_radar_background(rdev, chandef); -+ if (err) -+ return err; ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++- spin_lock_bh(&local->airtime[ac].lock); +++ spin_lock_bh(&local->active_txq_lock[ac]); ++ q_limit_l[ac] = sta->airtime[ac].aql_limit_low; ++ q_limit_h[ac] = sta->airtime[ac].aql_limit_high; ++- spin_unlock_bh(&local->airtime[ac].lock); +++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending); ++ } + -+@@ -1085,30 +1085,31 @@ cfg80211_start_offchan_radar_detection(s -+ if (!cac_time_ms) -+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; ++--- a/net/mac80211/ieee80211_i.h +++++ b/net/mac80211/ieee80211_i.h ++@@ -863,16 +863,20 @@ enum txq_info_flags { ++ * @def_flow: used as a fallback flow when a packet destined to @tin hashes to ++ * a fq_flow which is already owned by a different tin ++ * @def_cvars: codel vars for @def_flow ++- * @schedule_order: used with ieee80211_local->active_txqs ++ * @frags: used to keep fragments created after dequeue +++ * @schedule_order: used with ieee80211_local->active_txqs +++ * @schedule_round: counter to prevent infinite loops on TXQ scheduling ++ */ ++ struct txq_info { ++ struct fq_tin tin; ++ struct codel_vars def_cvars; ++ struct codel_stats cstats; ++- struct rb_node schedule_order; +++ +++ u16 schedule_round; +++ struct list_head schedule_order; + -+- rdev->offchan_radar_chandef = *chandef; -+- rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ -++ rdev->background_radar_chandef = *chandef; -++ rdev->background_radar_wdev = wdev; /* Get offchain ownership */ ++ struct sk_buff_head frags; +++ ++ unsigned long flags; + -+- __cfg80211_offchan_cac_event(rdev, wdev, chandef, -+- NL80211_RADAR_CAC_STARTED); -+- queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, -++ __cfg80211_background_cac_event(rdev, wdev, chandef, -++ NL80211_RADAR_CAC_STARTED); -++ queue_delayed_work(cfg80211_wq, &rdev->background_cac_done_wk, -+ msecs_to_jiffies(cac_time_ms)); ++ /* keep last! */ ++@@ -949,8 +953,6 @@ struct ieee80211_sub_if_data { ++ struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; ++ struct mac80211_qos_map __rcu *qos_map; + -+ return 0; ++- struct airtime_info airtime[IEEE80211_NUM_ACS]; ++- ++ struct work_struct csa_finalize_work; ++ bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ ++ struct cfg80211_chan_def csa_chandef; ++@@ -1185,44 +1187,6 @@ enum mac80211_scan_state { ++ SCAN_ABORT, ++ }; ++ ++-/** ++- * struct airtime_sched_info - state used for airtime scheduling and AQL ++- * ++- * @lock: spinlock that protects all the fields in this struct ++- * @active_txqs: rbtree of currently backlogged queues, sorted by virtual time ++- * @schedule_pos: the current position maintained while a driver walks the tree ++- * with ieee80211_next_txq() ++- * @active_list: list of struct airtime_info structs that were active within ++- * the last AIRTIME_ACTIVE_DURATION (100 ms), used to compute ++- * weight_sum ++- * @last_weight_update: used for rate limiting walking active_list ++- * @last_schedule_time: tracks the last time a transmission was scheduled; used ++- * for catching up v_t if no stations are eligible for ++- * transmission. ++- * @v_t: global virtual time; queues with v_t < this are eligible for ++- * transmission ++- * @weight_sum: total sum of all active stations used for dividing airtime ++- * @weight_sum_reciprocal: reciprocal of weight_sum (to avoid divisions in fast ++- * path - see comment above ++- * IEEE80211_RECIPROCAL_DIVISOR_64) ++- * @aql_txq_limit_low: AQL limit when total outstanding airtime ++- * is < IEEE80211_AQL_THRESHOLD ++- * @aql_txq_limit_high: AQL limit when total outstanding airtime ++- * is > IEEE80211_AQL_THRESHOLD ++- */ ++-struct airtime_sched_info { ++- spinlock_t lock; ++- struct rb_root_cached active_txqs; ++- struct rb_node *schedule_pos; ++- struct list_head active_list; ++- u64 last_weight_update; ++- u64 last_schedule_activity; ++- u64 v_t; ++- u64 weight_sum; ++- u64 weight_sum_reciprocal; ++- u32 aql_txq_limit_low; ++- u32 aql_txq_limit_high; ++-}; ++ DECLARE_STATIC_KEY_FALSE(aql_disable); ++ ++ struct ieee80211_local { ++@@ -1236,8 +1200,13 @@ struct ieee80211_local { ++ struct codel_params cparams; ++ ++ /* protects active_txqs and txqi->schedule_order */ ++- struct airtime_sched_info airtime[IEEE80211_NUM_ACS]; +++ spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; +++ struct list_head active_txqs[IEEE80211_NUM_ACS]; +++ u16 schedule_round[IEEE80211_NUM_ACS]; +++ ++ u16 airtime_flags; +++ u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; +++ u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; ++ u32 aql_threshold; ++ atomic_t aql_total_pending_airtime; ++ ++@@ -1654,125 +1623,6 @@ static inline bool txq_has_queue(struct ++ return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets); + } + -+-void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev) -++void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) ++-static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq) ++-{ ++- struct ieee80211_sub_if_data *sdata; ++- struct sta_info *sta; ++- ++- if (txq->sta) { ++- sta = container_of(txq->sta, struct sta_info, sta); ++- return &sta->airtime[txq->ac]; ++- } ++- ++- sdata = vif_to_sdata(txq->vif); ++- return &sdata->airtime[txq->ac]; ++-} ++- ++-/* To avoid divisions in the fast path, we keep pre-computed reciprocals for ++- * airtime weight calculations. There are two different weights to keep track ++- * of: The per-station weight and the sum of weights per phy. ++- * ++- * For the per-station weights (kept in airtime_info below), we use 32-bit ++- * reciprocals with a devisor of 2^19. This lets us keep the multiplications and ++- * divisions for the station weights as 32-bit operations at the cost of a bit ++- * of rounding error for high weights; but the choice of divisor keeps rounding ++- * errors <10% for weights <2^15, assuming no more than 8ms of airtime is ++- * reported at a time. ++- * ++- * For the per-phy sum of weights the values can get higher, so we use 64-bit ++- * operations for those with a 32-bit divisor, which should avoid any ++- * significant rounding errors. ++- */ ++-#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL ++-#define IEEE80211_RECIPROCAL_SHIFT_64 32 ++-#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U ++-#define IEEE80211_RECIPROCAL_SHIFT_32 19 ++- ++-static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight) ++-{ ++- if (air_info->weight == weight) ++- return; ++- ++- air_info->weight = weight; ++- if (weight) { ++- air_info->weight_reciprocal = ++- IEEE80211_RECIPROCAL_DIVISOR_32 / weight; ++- } else { ++- air_info->weight_reciprocal = 0; ++- } ++-} ++- ++-static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched, ++- int weight_sum) ++-{ ++- if (air_sched->weight_sum == weight_sum) ++- return; ++- ++- air_sched->weight_sum = weight_sum; ++- if (air_sched->weight_sum) { ++- air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64; ++- do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum); ++- } else { ++- air_sched->weight_sum_reciprocal = 0; ++- } ++-} ++- ++-/* A problem when trying to enforce airtime fairness is that we want to divide ++- * the airtime between the currently *active* stations. However, basing this on ++- * the instantaneous queue state of stations doesn't work, as queues tend to ++- * oscillate very quickly between empty and occupied, leading to the scheduler ++- * thinking only a single station is active when deciding whether to allow ++- * transmission (and thus not throttling correctly). ++- * ++- * To fix this we use a timer-based notion of activity: a station is considered ++- * active if it has been scheduled within the last 100 ms; we keep a separate ++- * list of all the stations considered active in this manner, and lazily update ++- * the total weight of active stations from this list (filtering the stations in ++- * the list by their 'last active' time). ++- * ++- * We add one additional safeguard to guard against stations that manage to get ++- * scheduled every 100 ms but don't transmit a lot of data, and thus don't use ++- * up any airtime. Such stations would be able to get priority for an extended ++- * period of time if they do start transmitting at full capacity again, and so ++- * we add an explicit maximum for how far behind a station is allowed to fall in ++- * the virtual airtime domain. This limit is set to a relatively high value of ++- * 20 ms because the main mechanism for catching up idle stations is the active ++- * state as described above; i.e., the hard limit should only be hit in ++- * pathological cases. ++- */ ++-#define AIRTIME_ACTIVE_DURATION (100 * NSEC_PER_MSEC) ++-#define AIRTIME_MAX_BEHIND 20000 /* 20 ms */ ++- ++-static inline bool airtime_is_active(struct airtime_info *air_info, u64 now) ++-{ ++- return air_info->last_scheduled >= now - AIRTIME_ACTIVE_DURATION; ++-} ++- ++-static inline void airtime_set_active(struct airtime_sched_info *air_sched, ++- struct airtime_info *air_info, u64 now) ++-{ ++- air_info->last_scheduled = now; ++- air_sched->last_schedule_activity = now; ++- list_move_tail(&air_info->list, &air_sched->active_list); ++-} ++- ++-static inline bool airtime_catchup_v_t(struct airtime_sched_info *air_sched, ++- u64 v_t, u64 now) ++-{ ++- air_sched->v_t = v_t; ++- return true; ++-} ++- ++-static inline void init_airtime_info(struct airtime_info *air_info, ++- struct airtime_sched_info *air_sched) ++-{ ++- atomic_set(&air_info->aql_tx_pending, 0); ++- air_info->aql_limit_low = air_sched->aql_txq_limit_low; ++- air_info->aql_limit_high = air_sched->aql_txq_limit_high; ++- airtime_weight_set(air_info, IEEE80211_DEFAULT_AIRTIME_WEIGHT); ++- INIT_LIST_HEAD(&air_info->list); ++-} ++- ++ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) + { -+ struct wiphy *wiphy = wdev->wiphy; -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ -+ lockdep_assert_wiphy(wiphy); -+ -+- if (wdev != rdev->offchan_radar_wdev) -++ if (wdev != rdev->background_radar_wdev) -+ return; -+ -+- rdev_set_radar_offchan(rdev, NULL); -+- rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ -++ rdev_set_radar_background(rdev, NULL); -++ rdev->background_radar_wdev = NULL; /* Release offchain ownership */ ++ return ether_addr_equal(raddr, addr) || ++@@ -2018,14 +1868,6 @@ int ieee80211_tx_control_port(struct wip ++ u64 *cookie); ++ int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, ++ const u8 *buf, size_t len); ++-void ieee80211_resort_txq(struct ieee80211_hw *hw, ++- struct ieee80211_txq *txq); ++-void ieee80211_unschedule_txq(struct ieee80211_hw *hw, ++- struct ieee80211_txq *txq, ++- bool purge); ++-void ieee80211_update_airtime_weight(struct ieee80211_local *local, ++- struct airtime_sched_info *air_sched, ++- u64 now, bool force); ++ ++ /* HT */ ++ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, ++--- a/net/mac80211/iface.c +++++ b/net/mac80211/iface.c ++@@ -2192,9 +2192,6 @@ int ieee80211_if_add(struct ieee80211_lo ++ } ++ } + -+- __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, -+- NL80211_RADAR_CAC_ABORTED); -++ __cfg80211_background_cac_event(rdev, wdev, -++ &rdev->background_radar_chandef, -++ NL80211_RADAR_CAC_ABORTED); -+ } -+--- a/net/wireless/nl80211.c -++++ b/net/wireless/nl80211.c -+@@ -796,7 +796,7 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_MBSSID_CONFIG] = -+ NLA_POLICY_NESTED(nl80211_mbssid_config_policy), -+ [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, -+- [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, -++ [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, -+ }; ++- for (i = 0; i < IEEE80211_NUM_ACS; i++) ++- init_airtime_info(&sdata->airtime[i], &local->airtime[i]); ++- ++ ieee80211_set_default_queues(sdata); + -+ /* policy for the key attributes */ -+@@ -9291,9 +9291,9 @@ static int nl80211_start_radar_detection -+ goto unlock; ++ sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; ++--- a/net/mac80211/main.c +++++ b/net/mac80211/main.c ++@@ -707,13 +707,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ ++ spin_lock_init(&local->queue_stop_reason_lock); ++ ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) { ++- struct airtime_sched_info *air_sched = &local->airtime[i]; ++- ++- air_sched->active_txqs = RB_ROOT_CACHED; ++- INIT_LIST_HEAD(&air_sched->active_list); ++- spin_lock_init(&air_sched->lock); ++- air_sched->aql_txq_limit_low = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; ++- air_sched->aql_txq_limit_high = +++ INIT_LIST_HEAD(&local->active_txqs[i]); +++ spin_lock_init(&local->active_txq_lock[i]); +++ local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; +++ local->aql_txq_limit_high[i] = ++ IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; + } + -+- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { -+- err = cfg80211_start_offchan_radar_detection(rdev, wdev, -+- &chandef); -++ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) { -++ err = cfg80211_start_background_radar_detection(rdev, wdev, -++ &chandef); -+ goto unlock; ++--- a/net/mac80211/rx.c +++++ b/net/mac80211/rx.c ++@@ -1583,8 +1583,12 @@ static void sta_ps_start(struct sta_info ++ ++ for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { ++ struct ieee80211_txq *txq = sta->sta.txq[tid]; +++ struct txq_info *txqi = to_txq_info(txq); ++ ++- ieee80211_unschedule_txq(&local->hw, txq, false); +++ spin_lock(&local->active_txq_lock[txq->ac]); +++ if (!list_empty(&txqi->schedule_order)) +++ list_del_init(&txqi->schedule_order); +++ spin_unlock(&local->active_txq_lock[txq->ac]); ++ ++ if (txq_has_queue(txq)) ++ set_bit(tid, &sta->txq_buffered_tids); ++--- a/net/mac80211/sta_info.c +++++ b/net/mac80211/sta_info.c ++@@ -426,11 +426,15 @@ struct sta_info *sta_info_alloc(struct i ++ if (sta_prepare_rate_control(local, sta, gfp)) ++ goto free_txq; ++ +++ sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT; ++ ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) { ++ skb_queue_head_init(&sta->ps_tx_buf[i]); ++ skb_queue_head_init(&sta->tx_filtered[i]); ++- init_airtime_info(&sta->airtime[i], &local->airtime[i]); +++ sta->airtime[i].deficit = sta->airtime_weight; +++ atomic_set(&sta->airtime[i].aql_tx_pending, 0); +++ sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i]; +++ sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i]; + } + -+--- a/net/wireless/rdev-ops.h -++++ b/net/wireless/rdev-ops.h -+@@ -1382,17 +1382,17 @@ static inline int rdev_color_change(stru ++ for (i = 0; i < IEEE80211_NUM_TIDS; i++) ++@@ -1889,59 +1893,24 @@ void ieee80211_sta_set_buffered(struct i + } ++ EXPORT_SYMBOL(ieee80211_sta_set_buffered); + -+ static inline int -+-rdev_set_radar_offchan(struct cfg80211_registered_device *rdev, -+- struct cfg80211_chan_def *chandef) -++rdev_set_radar_background(struct cfg80211_registered_device *rdev, -++ struct cfg80211_chan_def *chandef) ++-void ieee80211_register_airtime(struct ieee80211_txq *txq, ++- u32 tx_airtime, u32 rx_airtime) +++void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, +++ u32 tx_airtime, u32 rx_airtime) + { -+ struct wiphy *wiphy = &rdev->wiphy; -+ int ret; ++- struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); ++- struct ieee80211_local *local = sdata->local; ++- u64 weight_sum, weight_sum_reciprocal; ++- struct airtime_sched_info *air_sched; ++- struct airtime_info *air_info; +++ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); +++ struct ieee80211_local *local = sta->sdata->local; +++ u8 ac = ieee80211_ac_from_tid(tid); ++ u32 airtime = 0; ++ ++- air_sched = &local->airtime[txq->ac]; ++- air_info = to_airtime_info(txq); ++- ++- if (local->airtime_flags & AIRTIME_USE_TX) +++ if (sta->local->airtime_flags & AIRTIME_USE_TX) ++ airtime += tx_airtime; ++- if (local->airtime_flags & AIRTIME_USE_RX) +++ if (sta->local->airtime_flags & AIRTIME_USE_RX) ++ airtime += rx_airtime; ++ ++- /* Weights scale so the unit weight is 256 */ ++- airtime <<= 8; ++- ++- spin_lock_bh(&air_sched->lock); ++- ++- air_info->tx_airtime += tx_airtime; ++- air_info->rx_airtime += rx_airtime; ++- ++- if (air_sched->weight_sum) { ++- weight_sum = air_sched->weight_sum; ++- weight_sum_reciprocal = air_sched->weight_sum_reciprocal; ++- } else { ++- weight_sum = air_info->weight; ++- weight_sum_reciprocal = air_info->weight_reciprocal; ++- } ++- ++- /* Round the calculation of global vt */ ++- air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) * ++- weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64; ++- air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) * ++- air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32; ++- ieee80211_resort_txq(&local->hw, txq); ++- ++- spin_unlock_bh(&air_sched->lock); ++-} ++- ++-void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, ++- u32 tx_airtime, u32 rx_airtime) ++-{ ++- struct ieee80211_txq *txq = pubsta->txq[tid]; ++- ++- if (!txq) ++- return; ++- ++- ieee80211_register_airtime(txq, tx_airtime, rx_airtime); +++ spin_lock_bh(&local->active_txq_lock[ac]); +++ sta->airtime[ac].tx_airtime += tx_airtime; +++ sta->airtime[ac].rx_airtime += rx_airtime; +++ sta->airtime[ac].deficit -= airtime; +++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } ++ EXPORT_SYMBOL(ieee80211_sta_register_airtime); + -+- if (!rdev->ops->set_radar_offchan) -++ if (!rdev->ops->set_radar_background) -+ return -EOPNOTSUPP; ++@@ -2385,7 +2354,7 @@ void sta_set_sinfo(struct sta_info *sta, ++ } + -+- trace_rdev_set_radar_offchan(wiphy, chandef); -+- ret = rdev->ops->set_radar_offchan(wiphy, chandef); -++ trace_rdev_set_radar_background(wiphy, chandef); -++ ret = rdev->ops->set_radar_background(wiphy, chandef); -+ trace_rdev_return_int(wiphy, ret); ++ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { ++- sinfo->airtime_weight = sta->airtime[0].weight; +++ sinfo->airtime_weight = sta->airtime_weight; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); ++ } + -+ return ret; -+--- a/net/wireless/trace.h -++++ b/net/wireless/trace.h -+@@ -3646,7 +3646,7 @@ TRACE_EVENT(cfg80211_bss_color_notify, -+ __entry->color_bitmap) -+ ); ++--- a/net/mac80211/sta_info.h +++++ b/net/mac80211/sta_info.h ++@@ -135,25 +135,18 @@ enum ieee80211_agg_stop_reason { ++ #define AIRTIME_USE_TX BIT(0) ++ #define AIRTIME_USE_RX BIT(1) + -+-TRACE_EVENT(rdev_set_radar_offchan, -++TRACE_EVENT(rdev_set_radar_background, -+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), ++- ++ struct airtime_info { ++ u64 rx_airtime; ++ u64 tx_airtime; ++- u64 v_t; ++- u64 last_scheduled; ++- struct list_head list; +++ s64 deficit; ++ atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ ++ u32 aql_limit_low; ++ u32 aql_limit_high; ++- u32 weight_reciprocal; ++- u16 weight; ++ }; + -+ TP_ARGS(wiphy, chandef), -diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch -new file mode 100644 -index 0000000000..a135e3d1b5 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/323-mac80211-MBSSID-support-in-interface-handling.patch -@@ -0,0 +1,144 @@ -+From: John Crispin <john@phrozen.org> -+Date: Wed, 15 Sep 2021 19:54:35 -0700 -+Subject: [PATCH] mac80211: MBSSID support in interface handling -+ -+Configure multiple BSSID and enhanced multi-BSSID advertisement (EMA) -+parameters in mac80211 for AP mode. -+ -+For each interface, 'mbssid_tx_vif' points to the transmitting interface of -+the MBSSID set. The pointer is set to NULL if MBSSID is disabled. -+ -+Function ieee80211_stop() is modified to always bring down all the -+non-transmitting interfaces first and the transmitting interface last. -+ -+Signed-off-by: John Crispin <john@phrozen.org> -+Co-developed-by: Aloka Dixit <alokad@codeaurora.org> -+Signed-off-by: Aloka Dixit <alokad@codeaurora.org> -+Link: https://lore.kernel.org/r/20210916025437.29138-3-alokad@codeaurora.org -+[slightly change logic to be more obvious] -+Signed-off-by: Johannes Berg <johannes.berg@intel.com> -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -1719,6 +1719,7 @@ enum ieee80211_offload_flags { -+ * write-protected by sdata_lock and local->mtx so holding either is fine -+ * for read access. -+ * @color_change_color: the bss color that will be used after the change. -++ * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. -+ */ -+ struct ieee80211_vif { -+ enum nl80211_iftype type; -+@@ -1750,6 +1751,8 @@ struct ieee80211_vif { -+ bool color_change_active; -+ u8 color_change_color; ++ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, ++ struct sta_info *sta, u8 ac, ++ u16 tx_airtime, bool tx_completed); ++-void ieee80211_register_airtime(struct ieee80211_txq *txq, ++- u32 tx_airtime, u32 rx_airtime); + -++ struct ieee80211_vif *mbssid_tx_vif; -++ -+ /* must be last */ -+ u8 drv_priv[] __aligned(sizeof(void *)); -+ }; -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -112,6 +112,36 @@ static int ieee80211_set_mon_options(str -+ return 0; -+ } ++ struct sta_info; + -++static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata, -++ struct cfg80211_mbssid_config params) -++{ -++ struct ieee80211_sub_if_data *tx_sdata; -++ -++ sdata->vif.mbssid_tx_vif = NULL; -++ sdata->vif.bss_conf.bssid_index = 0; -++ sdata->vif.bss_conf.nontransmitted = false; -++ sdata->vif.bss_conf.ema_ap = false; -++ -++ if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) -++ return -EINVAL; -++ -++ tx_sdata = IEEE80211_WDEV_TO_SUB_IF(params.tx_wdev); -++ if (!tx_sdata) -++ return -EINVAL; -++ -++ if (tx_sdata == sdata) { -++ sdata->vif.mbssid_tx_vif = &sdata->vif; -++ } else { -++ sdata->vif.mbssid_tx_vif = &tx_sdata->vif; -++ sdata->vif.bss_conf.nontransmitted = true; -++ sdata->vif.bss_conf.bssid_index = params.index; -++ } -++ if (params.ema) -++ sdata->vif.bss_conf.ema_ap = true; -++ -++ return 0; -++} -++ -+ static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, -+ const char *name, -+ unsigned char name_assign_type, -+@@ -1107,6 +1137,14 @@ static int ieee80211_start_ap(struct wip -+ changed |= BSS_CHANGED_HE_BSS_COLOR; ++@@ -523,6 +516,7 @@ struct ieee80211_fragment_cache { ++ * @tid_seq: per-TID sequence numbers for sending to this STA ++ * @airtime: per-AC struct airtime_info describing airtime statistics for this ++ * station +++ * @airtime_weight: station weight for airtime fairness calculation purposes ++ * @ampdu_mlme: A-MPDU state machine state ++ * @mesh: mesh STA information ++ * @debugfs_dir: debug filesystem directory dentry ++@@ -653,6 +647,7 @@ struct sta_info { ++ u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; ++ ++ struct airtime_info airtime[IEEE80211_NUM_ACS]; +++ u16 airtime_weight; ++ ++ /* ++ * Aggregation information, locked with lock. ++--- a/net/mac80211/status.c +++++ b/net/mac80211/status.c ++@@ -983,25 +983,6 @@ static void __ieee80211_tx_status(struct ++ if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked) ++ ieee80211_frame_acked(sta, skb); ++ ++- } else if (wiphy_ext_feature_isset(local->hw.wiphy, ++- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { ++- struct ieee80211_sub_if_data *sdata; ++- struct ieee80211_txq *txq; ++- u32 airtime; ++- ++- /* Account airtime to multicast queue */ ++- sdata = ieee80211_sdata_from_skb(local, skb); ++- ++- if (sdata && (txq = sdata->vif.txq)) { ++- airtime = info->status.tx_time ?: ++- ieee80211_calc_expected_tx_airtime(hw, ++- &sdata->vif, ++- NULL, ++- skb->len, ++- false); ++- ++- ieee80211_register_airtime(txq, airtime, 0); ++- } + } + -++ if (sdata->vif.type == NL80211_IFTYPE_AP && -++ params->mbssid_config.tx_wdev) { -++ err = ieee80211_set_ap_mbssid_options(sdata, -++ params->mbssid_config); -++ if (err) -++ return err; -++ } -++ -+ mutex_lock(&local->mtx); -+ err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, -+ IEEE80211_CHANCTX_SHARED); -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -632,17 +632,46 @@ static void ieee80211_do_stop(struct iee -+ ieee80211_add_virtual_monitor(local); ++ /* SNMP counters ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -18,7 +18,6 @@ ++ #include <linux/bitmap.h> ++ #include <linux/rcupdate.h> ++ #include <linux/export.h> ++-#include <linux/timekeeping.h> ++ #include <net/net_namespace.h> ++ #include <net/ieee80211_radiotap.h> ++ #include <net/cfg80211.h> ++@@ -1480,7 +1479,7 @@ void ieee80211_txq_init(struct ieee80211 ++ codel_vars_init(&txqi->def_cvars); ++ codel_stats_init(&txqi->cstats); ++ __skb_queue_head_init(&txqi->frags); ++- RB_CLEAR_NODE(&txqi->schedule_order); +++ INIT_LIST_HEAD(&txqi->schedule_order); ++ ++ txqi->txq.vif = &sdata->vif; ++ ++@@ -1524,7 +1523,9 @@ void ieee80211_txq_purge(struct ieee8021 ++ ieee80211_purge_tx_queue(&local->hw, &txqi->frags); ++ spin_unlock_bh(&fq->lock); ++ ++- ieee80211_unschedule_txq(&local->hw, &txqi->txq, true); +++ spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); +++ list_del_init(&txqi->schedule_order); +++ spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); + } + -++static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata) -++{ -++ struct ieee80211_sub_if_data *tx_sdata, *non_tx_sdata, *tmp_sdata; -++ struct ieee80211_vif *tx_vif = sdata->vif.mbssid_tx_vif; -++ -++ if (!tx_vif) -++ return; -++ -++ tx_sdata = vif_to_sdata(tx_vif); -++ sdata->vif.mbssid_tx_vif = NULL; -++ -++ list_for_each_entry_safe(non_tx_sdata, tmp_sdata, -++ &tx_sdata->local->interfaces, list) { -++ if (non_tx_sdata != sdata && non_tx_sdata != tx_sdata && -++ non_tx_sdata->vif.mbssid_tx_vif == tx_vif && -++ ieee80211_sdata_running(non_tx_sdata)) { -++ non_tx_sdata->vif.mbssid_tx_vif = NULL; -++ dev_close(non_tx_sdata->wdev.netdev); -++ } -++ } -++ -++ if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata)) { -++ tx_sdata->vif.mbssid_tx_vif = NULL; -++ dev_close(tx_sdata->wdev.netdev); -++ } -++} -++ -+ static int ieee80211_stop(struct net_device *dev) ++ void ieee80211_txq_set_params(struct ieee80211_local *local) ++@@ -3819,259 +3820,102 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); ++ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) + { -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ -+- /* close all dependent VLAN interfaces before locking wiphy */ -++ /* close dependent VLAN and MBSSID interfaces before locking wiphy */ -+ if (sdata->vif.type == NL80211_IFTYPE_AP) { -+ struct ieee80211_sub_if_data *vlan, *tmpsdata; -+ -+ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, -+ u.vlan.list) -+ dev_close(vlan->dev); -++ -++ ieee80211_stop_mbssid(sdata); -+ } ++ struct ieee80211_local *local = hw_to_local(hw); ++- struct airtime_sched_info *air_sched; ++- u64 now = ktime_get_coarse_boottime_ns(); ++ struct ieee80211_txq *ret = NULL; ++- struct airtime_info *air_info; ++- struct txq_info *txqi = NULL; ++- struct rb_node *node; ++- bool first = false; +++ struct txq_info *txqi = NULL, *head = NULL; +++ bool found_eligible_txq = false; ++ ++- air_sched = &local->airtime[ac]; ++- spin_lock_bh(&air_sched->lock); +++ spin_lock_bh(&local->active_txq_lock[ac]); ++ ++- node = air_sched->schedule_pos; ++- ++-begin: ++- if (!node) { ++- node = rb_first_cached(&air_sched->active_txqs); ++- first = true; ++- } else { ++- node = rb_next(node); ++- } ++- ++- if (!node) ++- goto out; ++- ++- txqi = container_of(node, struct txq_info, schedule_order); ++- air_info = to_airtime_info(&txqi->txq); ++- ++- if (air_info->v_t > air_sched->v_t && ++- (!first || !airtime_catchup_v_t(air_sched, air_info->v_t, now))) +++ begin: +++ txqi = list_first_entry_or_null(&local->active_txqs[ac], +++ struct txq_info, +++ schedule_order); +++ if (!txqi) ++ goto out; + -+ wiphy_lock(sdata->local->hw.wiphy); -diff --git a/package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch -new file mode 100644 -index 0000000000..fdbcce9450 ---- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/324-mac80211-MBSSID-beacon-handling-in-AP-mode.patch -@@ -0,0 +1,326 @@ -+From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Thu, 24 Feb 2022 12:54:58 +0100 -+Subject: [PATCH] mac80211: MBSSID beacon handling in AP mode -+ -+Add new fields in struct beacon_data to store all MBSSID elements. -+Generate a beacon template which includes all MBSSID elements. -+Move CSA offset to reflect the MBSSID element length. -+ -+Co-developed-by: Aloka Dixit <alokad@codeaurora.org> -+Signed-off-by: Aloka Dixit <alokad@codeaurora.org> -+Co-developed-by: John Crispin <john@phrozen.org> -+Signed-off-by: John Crispin <john@phrozen.org> -+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Tested-by: Money Wang <money.wang@mediatek.com> -+Link: https://lore.kernel.org/r/5322db3c303f431adaf191ab31c45e151dde5465.1645702516.git.lorenzo@kernel.org -+[small cleanups] -+Signed-off-by: Johannes Berg <johannes.berg@intel.com> -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -4938,12 +4938,14 @@ void ieee80211_report_low_ack(struct iee -+ * @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets -+ * to countdown counters. This array can contain zero values which -+ * should be ignored. -++ * @mbssid_off: position of the multiple bssid element -+ */ -+ struct ieee80211_mutable_offsets { -+ u16 tim_offset; -+ u16 tim_length; ++- if (!ieee80211_txq_airtime_check(hw, &txqi->txq)) { ++- first = false; ++- goto begin; ++- } ++- ++- air_sched->schedule_pos = node; ++- air_sched->last_schedule_activity = now; ++- ret = &txqi->txq; ++-out: ++- spin_unlock_bh(&air_sched->lock); ++- return ret; ++-} ++-EXPORT_SYMBOL(ieee80211_next_txq); ++- ++-static void __ieee80211_insert_txq(struct rb_root_cached *root, ++- struct txq_info *txqi) ++-{ ++- struct rb_node **new = &root->rb_root.rb_node; ++- struct airtime_info *old_air, *new_air; ++- struct rb_node *parent = NULL; ++- struct txq_info *__txqi; ++- bool leftmost = true; ++- ++- while (*new) { ++- parent = *new; ++- __txqi = rb_entry(parent, struct txq_info, schedule_order); ++- old_air = to_airtime_info(&__txqi->txq); ++- new_air = to_airtime_info(&txqi->txq); ++- ++- if (new_air->v_t <= old_air->v_t) { ++- new = &parent->rb_left; ++- } else { ++- new = &parent->rb_right; ++- leftmost = false; ++- } +++ if (txqi == head) { +++ if (!found_eligible_txq) +++ goto out; +++ else +++ found_eligible_txq = false; ++ } + -+ u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; -++ u16 mbssid_off; -+ }; ++- rb_link_node(&txqi->schedule_order, parent, new); ++- rb_insert_color_cached(&txqi->schedule_order, root, leftmost); ++-} ++- ++-void ieee80211_resort_txq(struct ieee80211_hw *hw, ++- struct ieee80211_txq *txq) ++-{ ++- struct airtime_info *air_info = to_airtime_info(txq); ++- struct ieee80211_local *local = hw_to_local(hw); ++- struct txq_info *txqi = to_txq_info(txq); ++- struct airtime_sched_info *air_sched; ++- ++- air_sched = &local->airtime[txq->ac]; +++ if (!head) +++ head = txqi; + -+ /** -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -989,11 +989,29 @@ static int ieee80211_set_ftm_responder_p -+ return 0; ++- lockdep_assert_held(&air_sched->lock); ++- ++- if (!RB_EMPTY_NODE(&txqi->schedule_order)) { ++- struct airtime_info *a_prev = NULL, *a_next = NULL; ++- struct txq_info *t_prev, *t_next; ++- struct rb_node *n_prev, *n_next; +++ if (txqi->txq.sta) { +++ struct sta_info *sta = container_of(txqi->txq.sta, +++ struct sta_info, sta); +++ bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); +++ s64 deficit = sta->airtime[txqi->txq.ac].deficit; ++ ++- /* Erasing a node can cause an expensive rebalancing operation, ++- * so we check the previous and next nodes first and only remove ++- * and re-insert if the current node is not already in the ++- * correct position. ++- */ ++- if ((n_prev = rb_prev(&txqi->schedule_order)) != NULL) { ++- t_prev = container_of(n_prev, struct txq_info, ++- schedule_order); ++- a_prev = to_airtime_info(&t_prev->txq); ++- } +++ if (aql_check) +++ found_eligible_txq = true; ++ ++- if ((n_next = rb_next(&txqi->schedule_order)) != NULL) { ++- t_next = container_of(n_next, struct txq_info, ++- schedule_order); ++- a_next = to_airtime_info(&t_next->txq); +++ if (deficit < 0) +++ sta->airtime[txqi->txq.ac].deficit += +++ sta->airtime_weight; +++ +++ if (deficit < 0 || !aql_check) { +++ list_move_tail(&txqi->schedule_order, +++ &local->active_txqs[txqi->txq.ac]); +++ goto begin; ++ } ++- ++- if ((!a_prev || a_prev->v_t <= air_info->v_t) && ++- (!a_next || a_next->v_t > air_info->v_t)) ++- return; ++- ++- if (air_sched->schedule_pos == &txqi->schedule_order) ++- air_sched->schedule_pos = n_prev; ++- ++- rb_erase_cached(&txqi->schedule_order, ++- &air_sched->active_txqs); ++- RB_CLEAR_NODE(&txqi->schedule_order); ++- __ieee80211_insert_txq(&air_sched->active_txqs, txqi); ++ } ++-} ++- ++-void ieee80211_update_airtime_weight(struct ieee80211_local *local, ++- struct airtime_sched_info *air_sched, ++- u64 now, bool force) ++-{ ++- struct airtime_info *air_info, *tmp; ++- u64 weight_sum = 0; ++- ++- if (unlikely(!now)) ++- now = ktime_get_coarse_boottime_ns(); ++- ++- lockdep_assert_held(&air_sched->lock); ++- ++- if (!force && (air_sched->last_weight_update < ++- now - AIRTIME_ACTIVE_DURATION)) ++- return; ++- ++- list_for_each_entry_safe(air_info, tmp, ++- &air_sched->active_list, list) { ++- if (airtime_is_active(air_info, now)) ++- weight_sum += air_info->weight; ++- else ++- list_del_init(&air_info->list); ++- } ++- airtime_weight_sum_set(air_sched, weight_sum); ++- air_sched->last_weight_update = now; ++-} ++ ++-void ieee80211_schedule_txq(struct ieee80211_hw *hw, ++- struct ieee80211_txq *txq) ++- __acquires(txq_lock) __releases(txq_lock) ++-{ ++- struct ieee80211_local *local = hw_to_local(hw); ++- struct txq_info *txqi = to_txq_info(txq); ++- struct airtime_sched_info *air_sched; ++- u64 now = ktime_get_coarse_boottime_ns(); ++- struct airtime_info *air_info; ++- u8 ac = txq->ac; ++- bool was_active; ++ ++- air_sched = &local->airtime[ac]; ++- air_info = to_airtime_info(txq); ++- ++- spin_lock_bh(&air_sched->lock); ++- was_active = airtime_is_active(air_info, now); ++- airtime_set_active(air_sched, air_info, now); ++- ++- if (!RB_EMPTY_NODE(&txqi->schedule_order)) +++ if (txqi->schedule_round == local->schedule_round[ac]) ++ goto out; ++ ++- /* If the station has been inactive for a while, catch up its v_t so it ++- * doesn't get indefinite priority; see comment above the definition of ++- * AIRTIME_MAX_BEHIND. ++- */ ++- if ((!was_active && air_info->v_t < air_sched->v_t) || ++- air_info->v_t < air_sched->v_t - AIRTIME_MAX_BEHIND) ++- air_info->v_t = air_sched->v_t; ++- ++- ieee80211_update_airtime_weight(local, air_sched, now, !was_active); ++- __ieee80211_insert_txq(&air_sched->active_txqs, txqi); +++ list_del_init(&txqi->schedule_order); +++ txqi->schedule_round = local->schedule_round[ac]; +++ ret = &txqi->txq; ++ ++ out: ++- spin_unlock_bh(&air_sched->lock); ++-} ++-EXPORT_SYMBOL(ieee80211_schedule_txq); ++- ++-static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, ++- struct ieee80211_txq *txq, ++- bool purge) ++-{ ++- struct ieee80211_local *local = hw_to_local(hw); ++- struct txq_info *txqi = to_txq_info(txq); ++- struct airtime_sched_info *air_sched; ++- struct airtime_info *air_info; ++- ++- air_sched = &local->airtime[txq->ac]; ++- air_info = to_airtime_info(&txqi->txq); ++- ++- lockdep_assert_held(&air_sched->lock); ++- ++- if (purge) { ++- list_del_init(&air_info->list); ++- ieee80211_update_airtime_weight(local, air_sched, 0, true); ++- } ++- ++- if (RB_EMPTY_NODE(&txqi->schedule_order)) ++- return; ++- ++- if (air_sched->schedule_pos == &txqi->schedule_order) ++- air_sched->schedule_pos = rb_prev(&txqi->schedule_order); ++- ++- if (!purge) ++- airtime_set_active(air_sched, air_info, ++- ktime_get_coarse_boottime_ns()); ++- ++- rb_erase_cached(&txqi->schedule_order, ++- &air_sched->active_txqs); ++- RB_CLEAR_NODE(&txqi->schedule_order); +++ spin_unlock_bh(&local->active_txq_lock[ac]); +++ return ret; + } +++EXPORT_SYMBOL(ieee80211_next_txq); + -++static int -++ieee80211_copy_mbssid_beacon(u8 *pos, struct cfg80211_mbssid_elems *dst, -++ struct cfg80211_mbssid_elems *src) -++{ -++ int i, offset = 0; -++ -++ for (i = 0; i < src->cnt; i++) { -++ memcpy(pos + offset, src->elem[i].data, src->elem[i].len); -++ dst->elem[i].len = src->elem[i].len; -++ dst->elem[i].data = pos + offset; -++ offset += dst->elem[i].len; -++ } -++ dst->cnt = src->cnt; -++ -++ return offset; -++} -++ -+ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, -+ struct cfg80211_beacon_data *params, -+ const struct ieee80211_csa_settings *csa, -+ const struct ieee80211_color_change_settings *cca) ++-void ieee80211_unschedule_txq(struct ieee80211_hw *hw, +++void __ieee80211_schedule_txq(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq, ++- bool purge) ++- __acquires(txq_lock) __releases(txq_lock) ++-{ ++- struct ieee80211_local *local = hw_to_local(hw); ++- ++- spin_lock_bh(&local->airtime[txq->ac].lock); ++- __ieee80211_unschedule_txq(hw, txq, purge); ++- spin_unlock_bh(&local->airtime[txq->ac].lock); ++-} ++- ++-void ieee80211_return_txq(struct ieee80211_hw *hw, ++- struct ieee80211_txq *txq, bool force) +++ bool force) + { -++ struct cfg80211_mbssid_elems *mbssid = NULL; -+ struct beacon_data *new, *old; -+ int new_head_len, new_tail_len; -+ int size, err; -+@@ -1021,6 +1039,17 @@ static int ieee80211_assign_beacon(struc ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = to_txq_info(txq); ++ ++- spin_lock_bh(&local->airtime[txq->ac].lock); +++ spin_lock_bh(&local->active_txq_lock[txq->ac]); ++ ++- if (!RB_EMPTY_NODE(&txqi->schedule_order) && !force && ++- !txq_has_queue(txq)) ++- __ieee80211_unschedule_txq(hw, txq, false); +++ if (list_empty(&txqi->schedule_order) && +++ (force || !skb_queue_empty(&txqi->frags) || +++ txqi->tin.backlog_packets)) { +++ /* If airtime accounting is active, always enqueue STAs at the +++ * head of the list to ensure that they only get moved to the +++ * back by the airtime DRR scheduler once they have a negative +++ * deficit. A station that already has a negative deficit will +++ * get immediately moved to the back of the list on the next +++ * call to ieee80211_next_txq(). +++ */ +++ if (txqi->txq.sta && local->airtime_flags && +++ wiphy_ext_feature_isset(local->hw.wiphy, +++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) +++ list_add(&txqi->schedule_order, +++ &local->active_txqs[txq->ac]); +++ else +++ list_add_tail(&txqi->schedule_order, +++ &local->active_txqs[txq->ac]); +++ } + -+ size = sizeof(*new) + new_head_len + new_tail_len; ++- spin_unlock_bh(&local->airtime[txq->ac].lock); +++ spin_unlock_bh(&local->active_txq_lock[txq->ac]); ++ } ++-EXPORT_SYMBOL(ieee80211_return_txq); +++EXPORT_SYMBOL(__ieee80211_schedule_txq); + -++ /* new or old multiple BSSID elements? */ -++ if (params->mbssid_ies) { -++ mbssid = params->mbssid_ies; -++ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -++ size += ieee80211_get_mbssid_beacon_len(mbssid); -++ } else if (old && old->mbssid_ies) { -++ mbssid = old->mbssid_ies; -++ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -++ size += ieee80211_get_mbssid_beacon_len(mbssid); -++ } -++ -+ new = kzalloc(size, GFP_KERNEL); -+ if (!new) -+ return -ENOMEM; -+@@ -1029,12 +1058,20 @@ static int ieee80211_assign_beacon(struc ++ DEFINE_STATIC_KEY_FALSE(aql_disable); + -+ /* -+ * pointers go into the block we allocated, -+- * memory is | beacon_data | head | tail | -++ * memory is | beacon_data | head | tail | mbssid_ies -+ */ -+ new->head = ((u8 *) new) + sizeof(*new); -+ new->tail = new->head + new_head_len; -+ new->head_len = new_head_len; -+ new->tail_len = new_tail_len; -++ /* copy in optional mbssid_ies */ -++ if (mbssid) { -++ u8 *pos = new->tail + new->tail_len; -++ -++ new->mbssid_ies = (void *)pos; -++ pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); -++ ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid); -++ } ++ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++ { ++- struct airtime_info *air_info = to_airtime_info(txq); +++ struct sta_info *sta; ++ struct ieee80211_local *local = hw_to_local(hw); + -+ if (csa) { -+ new->cntdwn_current_counter = csa->count; -+@@ -1332,8 +1369,11 @@ static int ieee80211_stop_ap(struct wiph ++ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) ++@@ -4086,12 +3930,15 @@ bool ieee80211_txq_airtime_check(struct ++ if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) ++ return true; + -+ mutex_unlock(&local->mtx); ++- if (atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_low) +++ sta = container_of(txq->sta, struct sta_info, sta); +++ if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < +++ sta->airtime[txq->ac].aql_limit_low) ++ return true; + -+- kfree(sdata->u.ap.next_beacon); -+- sdata->u.ap.next_beacon = NULL; -++ if (sdata->u.ap.next_beacon) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -++ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -++ } ++ if (atomic_read(&local->aql_total_pending_airtime) < ++ local->aql_threshold && ++- atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_high) +++ atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < +++ sta->airtime[txq->ac].aql_limit_high) ++ return true; + -+ /* turn off carrier for this interface and dependent VLANs */ -+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) -+@@ -3126,12 +3166,24 @@ cfg80211_beacon_dup(struct cfg80211_beac ++ return false; ++@@ -4101,59 +3948,60 @@ EXPORT_SYMBOL(ieee80211_txq_airtime_chec ++ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++ { ++- struct txq_info *first_txqi = NULL, *txqi = to_txq_info(txq); ++ struct ieee80211_local *local = hw_to_local(hw); ++- struct airtime_sched_info *air_sched; ++- struct airtime_info *air_info; ++- struct rb_node *node = NULL; ++- bool ret = false; ++- u64 now; ++- +++ struct txq_info *iter, *tmp, *txqi = to_txq_info(txq); +++ struct sta_info *sta; +++ u8 ac = txq->ac; + -+ len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + -+ beacon->proberesp_ies_len + beacon->assocresp_ies_len + -+- beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len; -++ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len + -++ ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); ++- if (!ieee80211_txq_airtime_check(hw, txq)) ++- return false; +++ spin_lock_bh(&local->active_txq_lock[ac]); + -+ new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); -+ if (!new_beacon) -+ return NULL; ++- air_sched = &local->airtime[txq->ac]; ++- spin_lock_bh(&air_sched->lock); +++ if (!txqi->txq.sta) +++ goto out; + -++ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { -++ new_beacon->mbssid_ies = -++ kzalloc(struct_size(new_beacon->mbssid_ies, -++ elem, beacon->mbssid_ies->cnt), -++ GFP_KERNEL); -++ if (!new_beacon->mbssid_ies) { -++ kfree(new_beacon); -++ return NULL; -++ } -++ } -++ -+ pos = (u8 *)(new_beacon + 1); -+ if (beacon->head_len) { -+ new_beacon->head_len = beacon->head_len; -+@@ -3169,6 +3221,10 @@ cfg80211_beacon_dup(struct cfg80211_beac -+ memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); -+ pos += beacon->probe_resp_len; -+ } -++ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) -++ pos += ieee80211_copy_mbssid_beacon(pos, -++ new_beacon->mbssid_ies, -++ beacon->mbssid_ies); ++- if (RB_EMPTY_NODE(&txqi->schedule_order)) +++ if (list_empty(&txqi->schedule_order)) ++ goto out; + -+ /* might copy -1, meaning no changes requested */ -+ new_beacon->ftm_responder = beacon->ftm_responder; -+@@ -3206,8 +3262,11 @@ static int ieee80211_set_after_csa_beaco -+ case NL80211_IFTYPE_AP: -+ err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, -+ NULL, NULL); -+- kfree(sdata->u.ap.next_beacon); -+- sdata->u.ap.next_beacon = NULL; -++ if (sdata->u.ap.next_beacon) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -++ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -++ } ++- now = ktime_get_coarse_boottime_ns(); +++ list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], +++ schedule_order) { +++ if (iter == txqi) +++ break; + -+ if (err < 0) -+ return err; -+@@ -3362,8 +3421,12 @@ static int ieee80211_set_csa_beacon(stru -+ if ((params->n_counter_offsets_beacon > -+ IEEE80211_MAX_CNTDWN_COUNTERS_NUM) || -+ (params->n_counter_offsets_presp > -+- IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) -++ IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -++ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -+ return -EINVAL; ++- /* Like in ieee80211_next_txq(), make sure the first station in the ++- * scheduling order is eligible for transmission to avoid starvation. ++- */ ++- node = rb_first_cached(&air_sched->active_txqs); ++- if (node) { ++- first_txqi = container_of(node, struct txq_info, ++- schedule_order); ++- air_info = to_airtime_info(&first_txqi->txq); ++- ++- if (air_sched->v_t < air_info->v_t) ++- airtime_catchup_v_t(air_sched, air_info->v_t, now); +++ if (!iter->txq.sta) { +++ list_move_tail(&iter->schedule_order, +++ &local->active_txqs[ac]); +++ continue; ++ } +++ sta = container_of(iter->txq.sta, struct sta_info, sta); +++ if (sta->airtime[ac].deficit < 0) +++ sta->airtime[ac].deficit += sta->airtime_weight; +++ list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); ++ } + -+ csa.counter_offsets_beacon = params->counter_offsets_beacon; -+ csa.counter_offsets_presp = params->counter_offsets_presp; -+@@ -3373,7 +3436,9 @@ static int ieee80211_set_csa_beacon(stru ++- air_info = to_airtime_info(&txqi->txq); ++- if (air_info->v_t <= air_sched->v_t) { ++- air_sched->last_schedule_activity = now; ++- ret = true; ++- } +++ sta = container_of(txqi->txq.sta, struct sta_info, sta); +++ if (sta->airtime[ac].deficit >= 0) +++ goto out; +++ +++ sta->airtime[ac].deficit += sta->airtime_weight; +++ list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); +++ spin_unlock_bh(&local->active_txq_lock[ac]); + -+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa, NULL); -+ if (err < 0) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -+ return err; -+ } -+ *changed |= err; -+@@ -3463,8 +3528,11 @@ static int ieee80211_set_csa_beacon(stru -+ static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata) +++ return false; ++ out: ++- spin_unlock_bh(&air_sched->lock); ++- return ret; +++ if (!list_empty(&txqi->schedule_order)) +++ list_del_init(&txqi->schedule_order); +++ spin_unlock_bh(&local->active_txq_lock[ac]); +++ +++ return true; ++ } ++ EXPORT_SYMBOL(ieee80211_txq_may_transmit); ++ ++ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) + { -+ sdata->vif.color_change_active = false; -+- kfree(sdata->u.ap.next_beacon); -+- sdata->u.ap.next_beacon = NULL; -++ if (sdata->u.ap.next_beacon) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -++ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -++ } ++ struct ieee80211_local *local = hw_to_local(hw); ++- struct airtime_sched_info *air_sched = &local->airtime[ac]; ++ ++- spin_lock_bh(&air_sched->lock); ++- air_sched->schedule_pos = NULL; ++- spin_unlock_bh(&air_sched->lock); +++ spin_lock_bh(&local->active_txq_lock[ac]); +++ local->schedule_round[ac]++; +++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } ++ EXPORT_SYMBOL(ieee80211_txq_schedule_start); + -+ cfg80211_color_change_aborted_notify(sdata->dev); +diff --git a/package/kernel/mac80211/patches/subsys/331-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch b/package/kernel/mac80211/patches/subsys/331-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch +new file mode 100644 +index 0000000000..c006d3762a +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/331-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch +@@ -0,0 +1,52 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Mon, 20 Jun 2022 14:53:04 +0200 ++Subject: [PATCH] mac80211: make sta airtime deficit field s32 instead of ++ s64 ++ ++32 bit is more than enough range for the airtime deficit ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/debugfs_sta.c +++++ b/net/mac80211/debugfs_sta.c ++@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f ++ size_t bufsz = 400; ++ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; ++ u64 rx_airtime = 0, tx_airtime = 0; ++- s64 deficit[IEEE80211_NUM_ACS]; +++ s32 deficit[IEEE80211_NUM_ACS]; ++ ssize_t rv; ++ int ac; ++ ++@@ -219,7 +219,7 @@ static ssize_t sta_airtime_read(struct f ++ ++ p += scnprintf(p, bufsz + buf - p, ++ "RX: %llu us\nTX: %llu us\nWeight: %u\n" ++- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", +++ "Deficit: VO: %d us VI: %d us BE: %d us BK: %d us\n", ++ rx_airtime, tx_airtime, sta->airtime_weight, ++ deficit[0], deficit[1], deficit[2], deficit[3]); ++ ++--- a/net/mac80211/sta_info.h +++++ b/net/mac80211/sta_info.h ++@@ -138,7 +138,7 @@ enum ieee80211_agg_stop_reason { ++ struct airtime_info { ++ u64 rx_airtime; ++ u64 tx_airtime; ++- s64 deficit; +++ s32 deficit; ++ atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ ++ u32 aql_limit_low; ++ u32 aql_limit_high; ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -3847,7 +3847,7 @@ struct ieee80211_txq *ieee80211_next_txq ++ struct sta_info *sta = container_of(txqi->txq.sta, ++ struct sta_info, sta); ++ bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); ++- s64 deficit = sta->airtime[txqi->txq.ac].deficit; +++ s32 deficit = sta->airtime[txqi->txq.ac].deficit; ++ ++ if (aql_check) ++ found_eligible_txq = true; +diff --git a/package/kernel/mac80211/patches/subsys/332-mac80211-consider-aql_tx_pending-when-checking-airti.patch b/package/kernel/mac80211/patches/subsys/332-mac80211-consider-aql_tx_pending-when-checking-airti.patch +new file mode 100644 +index 0000000000..c214294603 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/332-mac80211-consider-aql_tx_pending-when-checking-airti.patch +@@ -0,0 +1,48 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Mon, 20 Jun 2022 14:59:09 +0200 ++Subject: [PATCH] mac80211: consider aql_tx_pending when checking airtime ++ deficit ++ ++When queueing packets for a station, deficit only gets added once the packets ++have been transmitted, which could be much later. During that time, a lot of ++temporary unfairness could happen, which could lead to bursty behavior. ++Fix this by subtracting the aql_tx_pending when checking the deficit in tx ++scheduling. ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -3817,6 +3817,13 @@ out: + } -+@@ -4202,8 +4270,11 @@ ieee80211_set_after_color_change_beacon( -+ -+ ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, -+ NULL, NULL); -+- kfree(sdata->u.ap.next_beacon); -+- sdata->u.ap.next_beacon = NULL; -++ if (sdata->u.ap.next_beacon) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -++ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -++ } ++ EXPORT_SYMBOL(ieee80211_tx_dequeue); + -+ if (ret < 0) -+ return ret; -+@@ -4246,7 +4317,11 @@ ieee80211_set_color_change_beacon(struct -+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_color_change, -+ NULL, &color_change); -+ if (err < 0) { -+- kfree(sdata->u.ap.next_beacon); -++ if (sdata->u.ap.next_beacon) { -++ kfree(sdata->u.ap.next_beacon->mbssid_ies); -++ kfree(sdata->u.ap.next_beacon); -++ sdata->u.ap.next_beacon = NULL; -++ } -+ return err; +++static inline s32 ieee80211_sta_deficit(struct sta_info *sta, u8 ac) +++{ +++ struct airtime_info *air_info = &sta->airtime[ac]; +++ +++ return air_info->deficit - atomic_read(&air_info->aql_tx_pending); +++} +++ ++ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) ++ { ++ struct ieee80211_local *local = hw_to_local(hw); ++@@ -3847,7 +3854,7 @@ struct ieee80211_txq *ieee80211_next_txq ++ struct sta_info *sta = container_of(txqi->txq.sta, ++ struct sta_info, sta); ++ bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); ++- s32 deficit = sta->airtime[txqi->txq.ac].deficit; +++ s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac); ++ ++ if (aql_check) ++ found_eligible_txq = true; ++@@ -3972,7 +3979,7 @@ bool ieee80211_txq_may_transmit(struct i ++ continue; + } -+ *changed |= err; ++ sta = container_of(iter->txq.sta, struct sta_info, sta); ++- if (sta->airtime[ac].deficit < 0) +++ if (ieee80211_sta_deficit(sta, ac) < 0) ++ sta->airtime[ac].deficit += sta->airtime_weight; ++ list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); ++ } +diff --git a/package/kernel/mac80211/patches/subsys/333-mac80211-keep-recently-active-tx-queues-in-schedulin.patch b/package/kernel/mac80211/patches/subsys/333-mac80211-keep-recently-active-tx-queues-in-schedulin.patch +new file mode 100644 +index 0000000000..317e4f0653 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/333-mac80211-keep-recently-active-tx-queues-in-schedulin.patch +@@ -0,0 +1,118 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Mon, 20 Jun 2022 20:52:50 +0200 ++Subject: [PATCH] mac80211: keep recently active tx queues in scheduling ++ list ++ ++This allows proper deficit accounting to ensure that they don't carry their ++deficit until the next time they become active ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h -+@@ -261,6 +261,7 @@ struct beacon_data { -+ struct ieee80211_meshconf_ie *meshconf; -+ u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; -+ u8 cntdwn_current_counter; -++ struct cfg80211_mbssid_elems *mbssid_ies; -+ struct rcu_head rcu_head; -+ }; ++@@ -83,6 +83,13 @@ extern const u8 ieee80211_ac_to_qos_mask + -+@@ -1083,6 +1084,20 @@ ieee80211_vif_get_shift(struct ieee80211 -+ return shift; -+ } ++ #define IEEE80211_MAX_NAN_INSTANCE_ID 255 + -++static inline int -++ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems) -++{ -++ int i, len = 0; -++ -++ if (!elems) -++ return 0; -++ -++ for (i = 0; i < elems->cnt; i++) -++ len += elems->elem[i].len; ++ -++ return len; -++} +++/* +++ * Keep a station's queues on the active list for deficit accounting purposes +++ * if it was active or queued during the last 100ms +++ */ +++#define AIRTIME_ACTIVE_DURATION (HZ / 10) ++ -+ enum { -+ IEEE80211_RX_MSG = 1, -+ IEEE80211_TX_STATUS_MSG = 2, ++ struct ieee80211_bss { ++ u32 device_ts_beacon, device_ts_presp; ++ ++--- a/net/mac80211/sta_info.h +++++ b/net/mac80211/sta_info.h ++@@ -138,6 +138,7 @@ enum ieee80211_agg_stop_reason { ++ struct airtime_info { ++ u64 rx_airtime; ++ u64 tx_airtime; +++ u32 last_active; ++ s32 deficit; ++ atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ ++ u32 aql_limit_low; +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c -+@@ -5041,6 +5041,19 @@ ieee80211_beacon_get_finish(struct ieee8 -+ IEEE80211_TX_CTL_FIRST_FRAGMENT; ++@@ -3824,6 +3824,36 @@ static inline s32 ieee80211_sta_deficit( ++ return air_info->deficit - atomic_read(&air_info->aql_tx_pending); + } + ++static void -++ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon) +++ieee80211_txq_set_active(struct txq_info *txqi) ++{ -++ int i; +++ struct sta_info *sta; ++ -++ if (!beacon->mbssid_ies) +++ if (!txqi->txq.sta) ++ return; ++ -++ for (i = 0; i < beacon->mbssid_ies->cnt; i++) -++ skb_put_data(skb, beacon->mbssid_ies->elem[i].data, -++ beacon->mbssid_ies->elem[i].len); +++ sta = container_of(txqi->txq.sta, struct sta_info, sta); +++ sta->airtime[txqi->txq.ac].last_active = (u32)jiffies; ++} ++ -+ static struct sk_buff * -+ ieee80211_beacon_get_ap(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+@@ -5054,6 +5067,7 @@ ieee80211_beacon_get_ap(struct ieee80211 -+ struct ieee80211_if_ap *ap = &sdata->u.ap; -+ struct sk_buff *skb = NULL; -+ u16 csa_off_base = 0; -++ int mbssid_len; -+ -+ if (beacon->cntdwn_counter_offsets[0]) { -+ if (!is_template) -+@@ -5063,11 +5077,12 @@ ieee80211_beacon_get_ap(struct ieee80211 +++static bool +++ieee80211_txq_keep_active(struct txq_info *txqi) +++{ +++ struct sta_info *sta; +++ u32 diff; +++ +++ if (!txqi->txq.sta) +++ return false; +++ +++ sta = container_of(txqi->txq.sta, struct sta_info, sta); +++ if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0) +++ return false; +++ +++ diff = (u32)jiffies - sta->airtime[txqi->txq.ac].last_active; +++ +++ return diff <= AIRTIME_ACTIVE_DURATION; +++} +++ ++ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) ++ { ++ struct ieee80211_local *local = hw_to_local(hw); ++@@ -3870,7 +3900,6 @@ struct ieee80211_txq *ieee80211_next_txq ++ } + } + -+ /* headroom, head length, -+- * tail length and maximum TIM length -++ * tail length, maximum TIM length and multiple BSSID length -+ */ -++ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); -+ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + -+ beacon->tail_len + 256 + -+- local->hw.extra_beacon_tailroom); -++ local->hw.extra_beacon_tailroom + mbssid_len); -+ if (!skb) -+ return NULL; -+ -+@@ -5081,6 +5096,11 @@ ieee80211_beacon_get_ap(struct ieee80211 -+ offs->tim_length = skb->len - beacon->head_len; -+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; ++- ++ if (txqi->schedule_round == local->schedule_round[ac]) ++ goto out; + -++ if (mbssid_len) { -++ ieee80211_beacon_add_mbssid(skb, beacon); -++ offs->mbssid_off = skb->len - mbssid_len; -++ } -++ -+ /* for AP the csa offsets are from tail */ -+ csa_off_base = skb->len; ++@@ -3890,12 +3919,13 @@ void __ieee80211_schedule_txq(struct iee ++ { ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = to_txq_info(txq); +++ bool has_queue; ++ ++ spin_lock_bh(&local->active_txq_lock[txq->ac]); ++ +++ has_queue = force || txq_has_queue(txq); ++ if (list_empty(&txqi->schedule_order) && ++- (force || !skb_queue_empty(&txqi->frags) || ++- txqi->tin.backlog_packets)) { +++ (has_queue || ieee80211_txq_keep_active(txqi))) { ++ /* If airtime accounting is active, always enqueue STAs at the ++ * head of the list to ensure that they only get moved to the ++ * back by the airtime DRR scheduler once they have a negative ++@@ -3903,7 +3933,7 @@ void __ieee80211_schedule_txq(struct iee ++ * get immediately moved to the back of the list on the next ++ * call to ieee80211_next_txq(). ++ */ ++- if (txqi->txq.sta && local->airtime_flags && +++ if (txqi->txq.sta && local->airtime_flags && has_queue && ++ wiphy_ext_feature_isset(local->hw.wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ list_add(&txqi->schedule_order, ++@@ -3911,6 +3941,8 @@ void __ieee80211_schedule_txq(struct iee ++ else ++ list_add_tail(&txqi->schedule_order, ++ &local->active_txqs[txq->ac]); +++ if (has_queue) +++ ieee80211_txq_set_active(txqi); + } -diff --git a/package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch b/package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch ++ ++ spin_unlock_bh(&local->active_txq_lock[txq->ac]); +diff --git a/package/kernel/mac80211/patches/subsys/334-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch b/package/kernel/mac80211/patches/subsys/334-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch new file mode 100644 -index 0000000000..38b0de180e +index 0000000000..42e1671ed6 --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/325-mac80211-MBSSID-channel-switch.patch -@@ -0,0 +1,52 @@ -+From: John Crispin <john@phrozen.org> -+Date: Thu, 24 Feb 2022 12:54:59 +0100 -+Subject: [PATCH] mac80211: MBSSID channel switch ++++ b/package/kernel/mac80211/patches/subsys/334-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch +@@ -0,0 +1,131 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Mon, 20 Jun 2022 21:26:34 +0200 ++Subject: [PATCH] mac80211: add a per-PHY AQL limit to improve fairness + -+Trigger ieee80211_csa_finish() on the non-transmitting interfaces -+when channel switch concludes on the transmitting interface. ++In order to maintain fairness, the amount of queueing needs to be limited ++beyond the simple per-station AQL budget, otherwise the driver can simply ++repeatedly do scheduling rounds until all queues that have not used their ++AQL budget become eligble. + -+Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Co-developed-by: Aloka Dixit <alokad@codeaurora.org> -+Signed-off-by: Aloka Dixit <alokad@codeaurora.org> -+Signed-off-by: John Crispin <john@phrozen.org> -+Link: https://lore.kernel.org/r/6fde4d7f9fa387494f46a7aa4a584478dcda06f1.1645702516.git.lorenzo@kernel.org -+Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++To be conservative, use the high AQL limit for the first txq and add half ++of the low AQL for each subsequent queue. ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -3247,9 +3247,31 @@ cfg80211_beacon_dup(struct cfg80211_beac -+ void ieee80211_csa_finish(struct ieee80211_vif *vif) -+ { -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -++ struct ieee80211_local *local = sdata->local; ++--- a/net/mac80211/ieee80211_i.h +++++ b/net/mac80211/ieee80211_i.h ++@@ -1216,6 +1216,7 @@ struct ieee80211_local { ++ u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; ++ u32 aql_threshold; ++ atomic_t aql_total_pending_airtime; +++ atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS]; ++ ++ const struct ieee80211_ops *ops; ++ ++--- a/net/mac80211/main.c +++++ b/net/mac80211/main.c ++@@ -712,6 +712,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ ++ local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; ++ local->aql_txq_limit_high[i] = ++ IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; +++ atomic_set(&local->aql_ac_pending_airtime[i], 0); ++ } + -+- ieee80211_queue_work(&sdata->local->hw, -+- &sdata->csa_finalize_work); -++ rcu_read_lock(); ++ local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX; ++--- a/net/mac80211/sta_info.c +++++ b/net/mac80211/sta_info.c ++@@ -1929,6 +1929,7 @@ void ieee80211_sta_update_pending_airtim ++ &sta->airtime[ac].aql_tx_pending); ++ ++ atomic_add(tx_airtime, &local->aql_total_pending_airtime); +++ atomic_add(tx_airtime, &local->aql_ac_pending_airtime[ac]); ++ return; ++ } ++ ++@@ -1940,14 +1941,17 @@ void ieee80211_sta_update_pending_airtim ++ tx_pending, 0); ++ } ++ +++ atomic_sub(tx_airtime, &local->aql_total_pending_airtime); ++ tx_pending = atomic_sub_return(tx_airtime, ++- &local->aql_total_pending_airtime); +++ &local->aql_ac_pending_airtime[ac]); ++ if (WARN_ONCE(tx_pending < 0, ++ "Device %s AC %d pending airtime underflow: %u, %u", ++ wiphy_name(local->hw.wiphy), ac, tx_pending, ++- tx_airtime)) ++- atomic_cmpxchg(&local->aql_total_pending_airtime, +++ tx_airtime)) { +++ atomic_cmpxchg(&local->aql_ac_pending_airtime[ac], ++ tx_pending, 0); +++ atomic_sub(tx_pending, &local->aql_total_pending_airtime); +++ } ++ } ++ ++ int sta_info_move_state(struct sta_info *sta, ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -3863,6 +3863,9 @@ struct ieee80211_txq *ieee80211_next_txq ++ ++ spin_lock_bh(&local->active_txq_lock[ac]); ++ +++ if (!local->schedule_round[ac]) +++ goto out; ++ -++ if (vif->mbssid_tx_vif == vif) { -++ /* Trigger ieee80211_csa_finish() on the non-transmitting -++ * interfaces when channel switch is received on -++ * transmitting interface -++ */ -++ struct ieee80211_sub_if_data *iter; ++ begin: ++ txqi = list_first_entry_or_null(&local->active_txqs[ac], ++ struct txq_info, ++@@ -3984,6 +3987,25 @@ bool ieee80211_txq_airtime_check(struct ++ } ++ EXPORT_SYMBOL(ieee80211_txq_airtime_check); ++ +++static bool +++ieee80211_txq_schedule_airtime_check(struct ieee80211_local *local, u8 ac) +++{ +++ unsigned int num_txq = 0; +++ struct txq_info *txq; +++ u32 aql_limit; ++ -++ list_for_each_entry_rcu(iter, &local->interfaces, list) { -++ if (!ieee80211_sdata_running(iter)) -++ continue; +++ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) +++ return true; ++ -++ if (iter == sdata || iter->vif.mbssid_tx_vif != vif) -++ continue; +++ list_for_each_entry(txq, &local->active_txqs[ac], schedule_order) +++ num_txq++; ++ -++ ieee80211_queue_work(&iter->local->hw, -++ &iter->csa_finalize_work); -++ } +++ aql_limit = (num_txq - 1) * local->aql_txq_limit_low[ac] / 2 + +++ local->aql_txq_limit_high[ac]; +++ +++ return atomic_read(&local->aql_ac_pending_airtime[ac]) < aql_limit; +++} +++ ++ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++ { ++@@ -4000,6 +4022,9 @@ bool ieee80211_txq_may_transmit(struct i ++ if (list_empty(&txqi->schedule_order)) ++ goto out; ++ +++ if (!ieee80211_txq_schedule_airtime_check(local, ac)) +++ goto out; +++ ++ list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], ++ schedule_order) { ++ if (iter == txqi) ++@@ -4039,7 +4064,15 @@ void ieee80211_txq_schedule_start(struct ++ struct ieee80211_local *local = hw_to_local(hw); ++ ++ spin_lock_bh(&local->active_txq_lock[ac]); ++- local->schedule_round[ac]++; +++ +++ if (ieee80211_txq_schedule_airtime_check(local, ac)) { +++ local->schedule_round[ac]++; +++ if (!local->schedule_round[ac]) +++ local->schedule_round[ac]++; +++ } else { +++ local->schedule_round[ac] = 0; ++ } -++ ieee80211_queue_work(&local->hw, &sdata->csa_finalize_work); ++ -++ rcu_read_unlock(); ++ spin_unlock_bh(&local->active_txq_lock[ac]); + } -+ EXPORT_SYMBOL(ieee80211_csa_finish); -+ -diff --git a/package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch b/package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch ++ EXPORT_SYMBOL(ieee80211_txq_schedule_start); +diff --git a/package/kernel/mac80211/patches/subsys/335-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch b/package/kernel/mac80211/patches/subsys/335-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch new file mode 100644 -index 0000000000..1955568607 +index 0000000000..df45a520fa --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/326-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch -@@ -0,0 +1,25 @@ -+From: Lorenzo Bianconi <lorenzo@kernel.org> -+Date: Thu, 24 Feb 2022 12:55:00 +0100 -+Subject: [PATCH] mac80211: update bssid_indicator in -+ ieee80211_assign_beacon ++++ b/package/kernel/mac80211/patches/subsys/335-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch +@@ -0,0 +1,58 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Sat, 25 Jun 2022 21:25:40 +0200 ++Subject: [PATCH] mac80211: add debugfs file to display per-phy AQL pending ++ airtime + -+Update bssid_indicator in ieee80211_bss_conf according to the -+number of bssid in the set. ++Now that the global pending airtime is more relevant for airtime fairness, ++it makes sense to make it accessible via debugfs for debugging + -+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> -+Link: https://lore.kernel.org/r/f92317e002fca9933f05a445fcefb4f53291d601.1645702516.git.lorenzo@kernel.org -+Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -1071,6 +1071,9 @@ static int ieee80211_assign_beacon(struc -+ new->mbssid_ies = (void *)pos; -+ pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); -+ ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid); -++ /* update bssid_indicator */ -++ sdata->vif.bss_conf.bssid_indicator = -++ ilog2(__roundup_pow_of_two(mbssid->cnt + 1)); -+ } ++--- a/net/mac80211/debugfs.c +++++ b/net/mac80211/debugfs.c ++@@ -201,6 +201,36 @@ static const struct file_operations airt ++ .llseek = default_llseek, ++ }; + -+ if (csa) { -diff --git a/package/kernel/mac80211/patches/subsys/329-mac80211-minstrel_ht-fix-where-rate-stats-are-stored.patch b/package/kernel/mac80211/patches/subsys/329-mac80211-minstrel_ht-fix-where-rate-stats-are-stored.patch +++static ssize_t aql_pending_read(struct file *file, +++ char __user *user_buf, +++ size_t count, loff_t *ppos) +++{ +++ struct ieee80211_local *local = file->private_data; +++ char buf[400]; +++ int len = 0; +++ +++ len = scnprintf(buf, sizeof(buf), +++ "AC AQL pending\n" +++ "VO %u us\n" +++ "VI %u us\n" +++ "BE %u us\n" +++ "BK %u us\n" +++ "total %u us\n", +++ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]), +++ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]), +++ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]), +++ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]), +++ atomic_read(&local->aql_total_pending_airtime)); +++ return simple_read_from_buffer(user_buf, count, ppos, +++ buf, len); +++} +++ +++static const struct file_operations aql_pending_ops = { +++ .read = aql_pending_read, +++ .open = simple_open, +++ .llseek = default_llseek, +++}; +++ ++ static ssize_t aql_txq_limit_read(struct file *file, ++ char __user *user_buf, ++ size_t count, ++@@ -628,6 +658,7 @@ void debugfs_hw_add(struct ieee80211_loc ++ DEBUGFS_ADD(hw_conf); ++ DEBUGFS_ADD_MODE(force_tx_status, 0600); ++ DEBUGFS_ADD_MODE(aql_enable, 0600); +++ DEBUGFS_ADD(aql_pending); ++ ++ if (local->ops->wake_tx_queue) ++ DEBUGFS_ADD_MODE(aqm, 0600); +diff --git a/package/kernel/mac80211/patches/subsys/336-mac80211-only-accumulate-airtime-deficit-for-active-.patch b/package/kernel/mac80211/patches/subsys/336-mac80211-only-accumulate-airtime-deficit-for-active-.patch +new file mode 100644 +index 0000000000..35f07c1a97 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/336-mac80211-only-accumulate-airtime-deficit-for-active-.patch +@@ -0,0 +1,36 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Sat, 25 Jun 2022 23:10:19 +0200 ++Subject: [PATCH] mac80211: only accumulate airtime deficit for active ++ clients ++ ++When a client does not generate any local tx activity, accumulating airtime ++deficit for the round-robin scheduler can be harmful. If this goes on for too ++long, the deficit could grow quite large, which might cause unreasonable ++initial latency once the client becomes active ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/sta_info.c +++++ b/net/mac80211/sta_info.c ++@@ -1900,6 +1900,7 @@ void ieee80211_sta_register_airtime(stru ++ struct ieee80211_local *local = sta->sdata->local; ++ u8 ac = ieee80211_ac_from_tid(tid); ++ u32 airtime = 0; +++ u32 diff; ++ ++ if (sta->local->airtime_flags & AIRTIME_USE_TX) ++ airtime += tx_airtime; ++@@ -1909,7 +1910,11 @@ void ieee80211_sta_register_airtime(stru ++ spin_lock_bh(&local->active_txq_lock[ac]); ++ sta->airtime[ac].tx_airtime += tx_airtime; ++ sta->airtime[ac].rx_airtime += rx_airtime; ++- sta->airtime[ac].deficit -= airtime; +++ +++ diff = (u32)jiffies - sta->airtime[ac].last_active; +++ if (diff <= AIRTIME_ACTIVE_DURATION) +++ sta->airtime[ac].deficit -= airtime; +++ ++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } ++ EXPORT_SYMBOL(ieee80211_sta_register_airtime); +diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch new file mode 100644 -index 0000000000..d7832acce5 +index 0000000000..74e857679e --- /dev/null -+++ b/package/kernel/mac80211/patches/subsys/329-mac80211-minstrel_ht-fix-where-rate-stats-are-stored.patch -@@ -0,0 +1,61 @@ -+From: Peter Seiderer <ps.report@gmx.net> -+Date: Mon, 4 Apr 2022 18:54:14 +0200 -+Subject: [PATCH] mac80211: minstrel_ht: fix where rate stats are stored (fixes -+ debugfs output) -+ -+Using an ath9k card the debugfs output of minstrel_ht looks like the following -+(note the zero values for the first four rates sum-of success/attempts): -+ -+ best ____________rate__________ ____statistics___ _____last____ ______sum-of________ -+mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] -+OFDM 1 DP 6.0M 272 1640 5.2 3.1 53.8 3 0 0 0 0 -+OFDM 1 C 9.0M 273 1104 7.7 4.6 53.8 4 0 0 0 0 -+OFDM 1 B 12.0M 274 836 10.0 6.0 53.8 4 0 0 0 0 -+OFDM 1 A S 18.0M 275 568 14.3 8.5 53.8 5 0 0 0 0 -+OFDM 1 S 24.0M 276 436 18.1 0.0 0.0 5 0 1 80 1778 -+OFDM 1 36.0M 277 300 24.9 0.0 0.0 0 0 1 0 107 -+OFDM 1 S 48.0M 278 236 30.4 0.0 0.0 0 0 0 0 75 -+OFDM 1 54.0M 279 212 33.0 0.0 0.0 0 0 0 0 72 -+ -+Total packet count:: ideal 16582 lookaround 885 -+Average # of aggregated frames per A-MPDU: 1.0 -+ -+Debugging showed that the rate statistics for the first four rates where -+stored in the MINSTREL_CCK_GROUP instead of the MINSTREL_OFDM_GROUP because -+in minstrel_ht_get_stats() the supported check was not honoured as done in -+various other places, e.g net/mac80211/rc80211_minstrel_ht_debugfs.c: -+ -+ 74 if (!(mi->supported[i] & BIT(j))) -+ 75 continue; -+ -+With the patch applied the output looks good: -+ -+ best ____________rate__________ ____statistics___ _____last____ ______sum-of________ -+mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] -+OFDM 1 D 6.0M 272 1640 5.2 5.2 100.0 3 0 0 1 1 -+OFDM 1 C 9.0M 273 1104 7.7 7.7 100.0 4 0 0 38 38 -+OFDM 1 B 12.0M 274 836 10.0 9.9 89.5 4 2 2 372 395 -+OFDM 1 A P 18.0M 275 568 14.3 14.3 97.2 5 52 53 6956 7181 -+OFDM 1 S 24.0M 276 436 18.1 0.0 0.0 0 0 1 6 163 -+OFDM 1 36.0M 277 300 24.9 0.0 0.0 0 0 1 0 35 -+OFDM 1 S 48.0M 278 236 30.4 0.0 0.0 0 0 0 0 38 -+OFDM 1 S 54.0M 279 212 33.0 0.0 0.0 0 0 0 0 38 -+ -+Total packet count:: ideal 7097 lookaround 287 -+Average # of aggregated frames per A-MPDU: 1.0 -+ -+Signed-off-by: Peter Seiderer <ps.report@gmx.net> ++++ b/package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch +@@ -0,0 +1,53 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Sun, 26 Jun 2022 11:43:25 +0200 ++Subject: [PATCH] mac80211: increase quantum for airtime scheduler ++ ++Given the typical AQL budget and queue length, a quantum of 256 with the ++default station weight often requires iterating over all queues frequently, ++until one of them becomes eligible. ++Improve performance by using 8 times station weight as scheduler quantum ++ ++Signed-off-by: Felix Fietkau <nbd@nbd.name> +--- + -+--- a/net/mac80211/rc80211_minstrel_ht.c -++++ b/net/mac80211/rc80211_minstrel_ht.c -+@@ -364,6 +364,9 @@ minstrel_ht_get_stats(struct minstrel_pr ++--- a/net/mac80211/ieee80211_i.h +++++ b/net/mac80211/ieee80211_i.h ++@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask ++ */ ++ #define AIRTIME_ACTIVE_DURATION (HZ / 10) + -+ group = MINSTREL_CCK_GROUP; -+ for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { -++ if (!(mi->supported[group] & BIT(idx))) -++ continue; +++#define AIRTIME_QUANTUM_SHIFT 3 ++ -+ if (rate->idx != mp->cck_rates[idx]) -+ continue; ++ struct ieee80211_bss { ++ u32 device_ts_beacon, device_ts_presp; ++ ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -3894,7 +3894,7 @@ struct ieee80211_txq *ieee80211_next_txq ++ ++ if (deficit < 0) ++ sta->airtime[txqi->txq.ac].deficit += ++- sta->airtime_weight; +++ sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; ++ ++ if (deficit < 0 || !aql_check) { ++ list_move_tail(&txqi->schedule_order, ++@@ -4037,7 +4037,8 @@ bool ieee80211_txq_may_transmit(struct i ++ } ++ sta = container_of(iter->txq.sta, struct sta_info, sta); ++ if (ieee80211_sta_deficit(sta, ac) < 0) ++- sta->airtime[ac].deficit += sta->airtime_weight; +++ sta->airtime[ac].deficit += sta->airtime_weight << +++ AIRTIME_QUANTUM_SHIFT; ++ list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); ++ } ++ ++@@ -4045,7 +4046,7 @@ bool ieee80211_txq_may_transmit(struct i ++ if (sta->airtime[ac].deficit >= 0) ++ goto out; ++ ++- sta->airtime[ac].deficit += sta->airtime_weight; +++ sta->airtime[ac].deficit += sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; ++ list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); ++ spin_unlock_bh(&local->active_txq_lock[ac]); + diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-minstrel_ht-clean-up-CCK-code.patch deleted file mode 100644 @@ -10954,6 +16794,42 @@ index abefde7109..0000000000 - if (!ms) - return -ENOMEM; - +diff --git a/package/kernel/mac80211/patches/subsys/339-mac80211-exclude-multicast-packets-from-AQL-pending-.patch b/package/kernel/mac80211/patches/subsys/339-mac80211-exclude-multicast-packets-from-AQL-pending-.patch +new file mode 100644 +index 0000000000..43c3e75d65 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/339-mac80211-exclude-multicast-packets-from-AQL-pending-.patch +@@ -0,0 +1,30 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Wed, 13 Jul 2022 07:32:26 +0200 ++Subject: [PATCH] mac80211: exclude multicast packets from AQL pending airtime ++ ++In AP mode, multicast traffic is handled very differently from normal traffic, ++especially if at least one client is in powersave mode. ++This means that multicast packets can be buffered a lot longer than normal ++unicast packets, and can eat up the AQL budget very quickly because of the low ++data rate. ++Along with the recent change to maintain a global PHY AQL limit, this can lead ++to significant latency spikes for unicast traffic. ++ ++Since queueing multicast to hardware is currently not constrained by AQL limits ++anyway, let's just exclude it from the AQL pending airtime calculation entirely. ++ ++Fixes: 8e4bac067105 ("wifi: mac80211: add a per-PHY AQL limit to improve fairness") ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/tx.c +++++ b/net/mac80211/tx.c ++@@ -3792,7 +3792,7 @@ begin: ++ encap_out: ++ IEEE80211_SKB_CB(skb)->control.vif = vif; ++ ++- if (vif && +++ if (tx.sta && ++ wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) { ++ bool ampdu = txq->ac != IEEE80211_AC_VO; ++ u32 airtime; diff --git a/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch b/package/kernel/mac80211/patches/subsys/339-mac80211-remove-legacy-minstrel-rate-control.patch deleted file mode 100644 index 96ee595ac1..0000000000 @@ -12390,6 +18266,104 @@ index 9b6a614aa8..0000000000 - u32 sample_switch; - unsigned int cw_min; - unsigned int cw_max; +diff --git a/package/kernel/mac80211/patches/subsys/340-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch b/package/kernel/mac80211/patches/subsys/340-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch +new file mode 100644 +index 0000000000..82243f1d98 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/340-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch +@@ -0,0 +1,46 @@ ++From aa40d5a43526cca9439a2b45fcfdcd016594dece Mon Sep 17 00:00:00 2001 ++From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> ++Date: Sun, 17 Jul 2022 21:21:52 +0900 ++Subject: [PATCH] wifi: mac80211: do not abuse fq.lock in ieee80211_do_stop() ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++lockdep complains use of uninitialized spinlock at ieee80211_do_stop() [1], ++for commit f856373e2f31ffd3 ("wifi: mac80211: do not wake queues on a vif ++that is being stopped") guards clear_bit() using fq.lock even before ++fq_init() from ieee80211_txq_setup_flows() initializes this spinlock. ++ ++According to discussion [2], Toke was not happy with expanding usage of ++fq.lock. Since __ieee80211_wake_txqs() is called under RCU read lock, we ++can instead use synchronize_rcu() for flushing ieee80211_wake_txqs(). ++ ++Link: https://syzkaller.appspot.com/bug?extid=eceab52db7c4b961e9d6 [1] ++Link: https://lkml.kernel.org/r/874k0zowh2.fsf@toke.dk [2] ++Reported-by: syzbot <syzbot+eceab52db7c4b961e9d6@syzkaller.appspotmail.com> ++Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> ++Fixes: f856373e2f31ffd3 ("wifi: mac80211: do not wake queues on a vif that is being stopped") ++Tested-by: syzbot <syzbot+eceab52db7c4b961e9d6@syzkaller.appspotmail.com> ++Acked-by: Toke Høiland-Jørgensen <toke@kernel.org> ++Signed-off-by: Kalle Valo <kvalo@kernel.org> ++Link: https://lore.kernel.org/r/9cc9b81d-75a3-3925-b612-9d0ad3cab82b@I-love.SAKURA.ne.jp ++[ pick up commit 3598cb6e1862 ("wifi: mac80211: do not abuse fq.lock in ieee80211_do_stop()") from -next] ++Link: https://lore.kernel.org/all/87o7xcq6qt.fsf@kernel.org/ ++Signed-off-by: Jakub Kicinski <kuba@kernel.org> ++--- ++ net/mac80211/iface.c | 3 +-- ++ 1 file changed, 1 insertion(+), 2 deletions(-) ++ ++--- a/net/mac80211/iface.c +++++ b/net/mac80211/iface.c ++@@ -377,9 +377,8 @@ static void ieee80211_do_stop(struct iee ++ bool cancel_scan; ++ struct cfg80211_nan_func *func; ++ ++- spin_lock_bh(&local->fq.lock); ++ clear_bit(SDATA_STATE_RUNNING, &sdata->state); ++- spin_unlock_bh(&local->fq.lock); +++ synchronize_rcu(); /* flush _ieee80211_wake_txqs() */ ++ ++ cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; ++ if (cancel_scan) +diff --git a/package/kernel/mac80211/patches/subsys/341-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch b/package/kernel/mac80211/patches/subsys/341-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch +new file mode 100644 +index 0000000000..8c56acbf88 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/341-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch +@@ -0,0 +1,40 @@ ++From: Alexander Wetzel <alexander@wetzel-home.de> ++Date: Thu, 15 Sep 2022 14:41:20 +0200 ++Subject: [PATCH] mac80211: Fix deadlock: Don't start TX while holding ++ fq->lock ++ ++ieee80211_txq_purge() calls fq_tin_reset() and ++ieee80211_purge_tx_queue(); Both are then calling ++ieee80211_free_txskb(). Which can decide to TX the skb again. ++ ++There are at least two ways to get a deadlock: ++ ++1) When we have a TDLS teardown packet queued in either tin or frags ++ ieee80211_tdls_td_tx_handle() will call ieee80211_subif_start_xmit() ++ while we still hold fq->lock. ieee80211_txq_enqueue() will thus ++ deadlock. ++ ++2) A variant of the above happens if aggregation is up and running: ++ In that case ieee80211_iface_work() will deadlock with the original ++ task: The original tasks already holds fq->lock and tries to get ++ sta->lock after kicking off ieee80211_iface_work(). But the worker ++ can get sta->lock prior to the original task and will then spin for ++ fq->lock. ++ ++Avoid these deadlocks by not sending out any skbs when called via ++ieee80211_free_txskb(). ++ ++Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> ++--- ++ ++--- a/net/mac80211/status.c +++++ b/net/mac80211/status.c ++@@ -698,7 +698,7 @@ static void ieee80211_report_used_skb(st ++ ++ if (!sdata) { ++ skb->dev = NULL; ++- } else { +++ } else if (!dropped) { ++ unsigned int hdr_size = ++ ieee80211_hdrlen(hdr->frame_control); ++ diff --git a/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch b/package/kernel/mac80211/patches/subsys/341-mac80211-minstrel_ht-improve-ampdu-length-estimation.patch deleted file mode 100644 index a8e6e89954..0000000000 @@ -12463,6 +18437,59 @@ index a8e6e89954..0000000000 - static bool - minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group, - int tp_idx, const struct mcs_group *group) +diff --git a/package/kernel/mac80211/patches/subsys/342-mac80211-Ensure-vif-queues-are-operational-after-sta.patch b/package/kernel/mac80211/patches/subsys/342-mac80211-Ensure-vif-queues-are-operational-after-sta.patch +new file mode 100644 +index 0000000000..4310329319 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/342-mac80211-Ensure-vif-queues-are-operational-after-sta.patch +@@ -0,0 +1,47 @@ ++From: Alexander Wetzel <alexander@wetzel-home.de> ++Date: Thu, 15 Sep 2022 15:09:46 +0200 ++Subject: [PATCH] mac80211: Ensure vif queues are operational after start ++ ++Make sure local->queue_stop_reasons and vif.txqs_stopped stay in sync. ++ ++When a new vif is created the queues may end up in an inconsistent state ++and be inoperable: ++Communication not using iTXQ will work, allowing to e.g. complete the ++association. But the 4-way handshake will time out. The sta will not ++send out any skbs queued in iTXQs. ++ ++All normal attempts to start the queues will fail when reaching this ++state. ++local->queue_stop_reasons will have marked all queues as operational but ++vif.txqs_stopped will still be set, creating an inconsistent internal ++state. ++ ++In reality this seems to be race between the mac80211 function ++ieee80211_do_open() setting SDATA_STATE_RUNNING and the wake_txqs_tasklet: ++Depending on the driver and the timing the queues may end up to be ++operational or not. ++ ++Cc: stable@vger.kernel.org ++Fixes: f856373e2f31 ("wifi: mac80211: do not wake queues on a vif that is being stopped") ++Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> ++--- ++ ++--- a/net/mac80211/util.c +++++ b/net/mac80211/util.c ++@@ -301,14 +301,14 @@ static void __ieee80211_wake_txqs(struct ++ local_bh_disable(); ++ spin_lock(&fq->lock); ++ +++ sdata->vif.txqs_stopped[ac] = false; +++ ++ if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) ++ goto out; ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) ++ ps = &sdata->bss->ps; ++ ++- sdata->vif.txqs_stopped[ac] = false; ++- ++ list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ if (sdata != sta->sdata) ++ continue; diff --git a/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch b/package/kernel/mac80211/patches/subsys/342-mac80211-minstrel_ht-improve-sample-rate-selection.patch deleted file mode 100644 index e084525235..0000000000 @@ -12630,6 +18657,49 @@ index 0dbfa9d4fb..0000000000 - /* Try to increase robustness of max_prob_rate*/ - minstrel_ht_prob_rate_reduce_streams(mi); - +diff --git a/package/kernel/mac80211/patches/subsys/343-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch b/package/kernel/mac80211/patches/subsys/343-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch +new file mode 100644 +index 0000000000..0feb408d21 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/343-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch +@@ -0,0 +1,37 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Wed, 28 Sep 2022 13:50:34 +0200 ++Subject: [PATCH] wifi: mac80211: fix decap offload for stations on AP_VLAN ++ interfaces ++ ++Since AP_VLAN interfaces are not passed to the driver, check offload_flags ++on the bss vif instead. ++ ++Reported-by: Howard Hsu <howard-yh.hsu@mediatek.com> ++Fixes: 80a915ec4427 ("mac80211: add rx decapsulation offload support") ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/rx.c +++++ b/net/mac80211/rx.c ++@@ -4265,6 +4265,7 @@ void ieee80211_check_fast_rx(struct sta_ ++ .vif_type = sdata->vif.type, ++ .control_port_protocol = sdata->control_port_protocol, ++ }, *old, *new = NULL; +++ u32 offload_flags; ++ bool set_offload = false; ++ bool assign = false; ++ bool offload; ++@@ -4380,10 +4381,10 @@ void ieee80211_check_fast_rx(struct sta_ ++ if (assign) ++ new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); ++ ++- offload = assign && ++- (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED); +++ offload_flags = get_bss_sdata(sdata)->vif.offload_flags; +++ offload = offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED; ++ ++- if (offload) +++ if (assign && offload) ++ set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); ++ else ++ set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); diff --git a/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch b/package/kernel/mac80211/patches/subsys/344-mac80211-minstrel_ht-increase-stats-update-interval.patch deleted file mode 100644 index 9972a9414e..0000000000 @@ -12656,6 +18726,111 @@ index 9972a9414e..0000000000 - - minstrel_ht_init_cck_rates(mp); - for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++) +diff --git a/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch b/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch +new file mode 100644 +index 0000000000..161c7d6c8f +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/344-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch +@@ -0,0 +1,99 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Fri, 7 Oct 2022 10:54:47 +0200 ++Subject: [PATCH] wifi: cfg80211: fix ieee80211_data_to_8023_exthdr ++ handling of small packets ++ ++STP topology change notification packets only have a payload of 7 bytes, ++so they get dropped due to the skb->len < hdrlen + 8 check. ++Fix this by removing skb->len based checks and instead check the return code ++on the skb_copy_bits calls. ++ ++Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer") ++Reported-by: Chad Monroe <chad.monroe@smartrg.com> ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/wireless/util.c +++++ b/net/wireless/util.c ++@@ -557,7 +557,7 @@ int ieee80211_data_to_8023_exthdr(struct ++ return -1; ++ ++ hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; ++- if (skb->len < hdrlen + 8) +++ if (skb->len < hdrlen) ++ return -1; ++ ++ /* convert IEEE 802.11 header + possible LLC headers into Ethernet ++@@ -572,8 +572,9 @@ int ieee80211_data_to_8023_exthdr(struct ++ memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); ++ memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); ++ ++- if (iftype == NL80211_IFTYPE_MESH_POINT) ++- skb_copy_bits(skb, hdrlen, &mesh_flags, 1); +++ if (iftype == NL80211_IFTYPE_MESH_POINT && +++ skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) +++ return -1; ++ ++ mesh_flags &= MESH_FLAGS_AE; ++ ++@@ -593,11 +594,12 @@ int ieee80211_data_to_8023_exthdr(struct ++ if (iftype == NL80211_IFTYPE_MESH_POINT) { ++ if (mesh_flags == MESH_FLAGS_AE_A4) ++ return -1; ++- if (mesh_flags == MESH_FLAGS_AE_A5_A6) { ++- skb_copy_bits(skb, hdrlen + ++- offsetof(struct ieee80211s_hdr, eaddr1), ++- tmp.h_dest, 2 * ETH_ALEN); ++- } +++ if (mesh_flags == MESH_FLAGS_AE_A5_A6 && +++ skb_copy_bits(skb, hdrlen + +++ offsetof(struct ieee80211s_hdr, eaddr1), +++ tmp.h_dest, 2 * ETH_ALEN) < 0) +++ return -1; +++ ++ hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); ++ } ++ break; ++@@ -611,10 +613,11 @@ int ieee80211_data_to_8023_exthdr(struct ++ if (iftype == NL80211_IFTYPE_MESH_POINT) { ++ if (mesh_flags == MESH_FLAGS_AE_A5_A6) ++ return -1; ++- if (mesh_flags == MESH_FLAGS_AE_A4) ++- skb_copy_bits(skb, hdrlen + ++- offsetof(struct ieee80211s_hdr, eaddr1), ++- tmp.h_source, ETH_ALEN); +++ if (mesh_flags == MESH_FLAGS_AE_A4 && +++ skb_copy_bits(skb, hdrlen + +++ offsetof(struct ieee80211s_hdr, eaddr1), +++ tmp.h_source, ETH_ALEN) < 0) +++ return -1; ++ hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); ++ } ++ break; ++@@ -626,18 +629,18 @@ int ieee80211_data_to_8023_exthdr(struct ++ break; ++ } ++ ++- skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); ++- tmp.h_proto = payload.proto; ++- ++- if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && ++- tmp.h_proto != htons(ETH_P_AARP) && ++- tmp.h_proto != htons(ETH_P_IPX)) || ++- ether_addr_equal(payload.hdr, bridge_tunnel_header))) +++ if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && +++ ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && +++ payload.proto != htons(ETH_P_AARP) && +++ payload.proto != htons(ETH_P_IPX)) || +++ ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { ++ /* remove RFC1042 or Bridge-Tunnel encapsulation and ++ * replace EtherType */ ++ hdrlen += ETH_ALEN + 2; ++- else +++ tmp.h_proto = payload.proto; +++ } else { ++ tmp.h_proto = htons(skb->len - hdrlen); +++ } ++ ++ pskb_pull(skb, hdrlen); ++ diff --git a/package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch b/package/kernel/mac80211/patches/subsys/345-mac80211-minstrel_ht-fix-rounding-error-in-throughpu.patch deleted file mode 100644 index 1df5dec039..0000000000 @@ -12696,6 +18871,37 @@ index 1df5dec039..0000000000 - } - - /* +diff --git a/package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch b/package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch +new file mode 100644 +index 0000000000..16cafc447c +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/345-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch +@@ -0,0 +1,25 @@ ++From: Felix Fietkau <nbd@nbd.name> ++Date: Fri, 7 Oct 2022 10:58:26 +0200 ++Subject: [PATCH] wifi: mac80211: do not drop packets smaller than the ++ LLC-SNAP header on fast-rx ++ ++Since STP TCN frames are only 7 bytes, the pskb_may_pull call returns an error. ++Instead of dropping those packets, bump them back to the slow path for proper ++processing. ++ ++Fixes: 49ddf8e6e234 ("mac80211: add fast-rx path") ++Reported-by: Chad Monroe <chad.monroe@smartrg.com> ++Signed-off-by: Felix Fietkau <nbd@nbd.name> ++--- ++ ++--- a/net/mac80211/rx.c +++++ b/net/mac80211/rx.c ++@@ -4601,7 +4601,7 @@ static bool ieee80211_invoke_fast_rx(str ++ ++ if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { ++ if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) ++- goto drop; +++ return false; ++ ++ payload = (void *)(skb->data + snap_offs); ++ diff --git a/package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch b/package/kernel/mac80211/patches/subsys/346-mac80211-minstrel_ht-use-bitfields-to-encode-rate-in.patch deleted file mode 100644 index 6aa6f0ed93..0000000000 @@ -14055,6 +20261,130 @@ index 09f6fd2214..0000000000 - u8 band; - - /* Bitfield of supported MCS rates of all groups */ +diff --git a/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch b/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch +new file mode 100644 +index 0000000000..1e3486accd +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch +@@ -0,0 +1,118 @@ ++From 6d945a33f2b0aa24fc210dadaa0af3e8218e7002 Mon Sep 17 00:00:00 2001 ++From: Lorenzo Bianconi <lorenzo@kernel.org> ++Date: Fri, 25 Mar 2022 11:42:41 +0100 ++Subject: [PATCH] mac80211: introduce BSS color collision detection ++ ++Add ieee80211_rx_check_bss_color_collision routine in order to introduce ++BSS color collision detection in mac80211 if it is not supported in HW/FW ++(e.g. for mt7915 chipset). ++Add IEEE80211_HW_DETECTS_COLOR_COLLISION flag to let the driver notify ++BSS color collision detection is supported in HW/FW. Set this for ath11k ++which apparently didn't need this code. ++ ++Tested-by: Peter Chiu <Chui-Hao.Chiu@mediatek.com> ++Co-developed-by: Ryder Lee <ryder.lee@mediatek.com> ++Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> ++Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> ++Link: https://lore.kernel.org/r/a05eeeb1841a84560dc5aaec77894fcb69a54f27.1648204871.git.lorenzo@kernel.org ++[clarify commit message a bit, move flag to mac80211] ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++--- ++ drivers/net/wireless/ath/ath11k/mac.c | 5 ++- ++ include/net/mac80211.h | 4 +++ ++ net/mac80211/debugfs.c | 1 + ++ net/mac80211/rx.c | 46 +++++++++++++++++++++++++++ ++ 4 files changed, 55 insertions(+), 1 deletion(-) ++ ++--- a/include/net/mac80211.h +++++ b/include/net/mac80211.h ++@@ -2418,6 +2418,9 @@ struct ieee80211_txq { ++ * usage and 802.11 frames with %RX_FLAG_ONLY_MONITOR set for monitor to ++ * the stack. ++ * +++ * @IEEE80211_HW_DETECTS_COLOR_COLLISION: HW/driver has support for BSS color +++ * collision detection and doesn't need it in software. +++ * ++ * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays ++ */ ++ enum ieee80211_hw_flags { ++@@ -2473,6 +2476,7 @@ enum ieee80211_hw_flags { ++ IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD, ++ IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD, ++ IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP, +++ IEEE80211_HW_DETECTS_COLOR_COLLISION, ++ ++ /* keep last, obviously */ ++ NUM_IEEE80211_HW_FLAGS ++--- a/net/mac80211/debugfs.c +++++ b/net/mac80211/debugfs.c ++@@ -494,6 +494,7 @@ static const char *hw_flag_names[] = { ++ FLAG(SUPPORTS_TX_ENCAP_OFFLOAD), ++ FLAG(SUPPORTS_RX_DECAP_OFFLOAD), ++ FLAG(SUPPORTS_CONC_MON_RX_DECAP), +++ FLAG(DETECTS_COLOR_COLLISION), ++ #undef FLAG ++ }; ++ ++--- a/net/mac80211/rx.c +++++ b/net/mac80211/rx.c ++@@ -3180,6 +3180,49 @@ static void ieee80211_process_sa_query_r ++ ieee80211_tx_skb(sdata, skb); ++ } ++ +++static void +++ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx) +++{ +++ struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; +++ const struct element *ie; +++ size_t baselen; +++ +++ if (!wiphy_ext_feature_isset(rx->local->hw.wiphy, +++ NL80211_EXT_FEATURE_BSS_COLOR)) +++ return; +++ +++ if (ieee80211_hw_check(&rx->local->hw, DETECTS_COLOR_COLLISION)) +++ return; +++ +++ if (rx->sdata->vif.csa_active) +++ return; +++ +++ baselen = mgmt->u.beacon.variable - rx->skb->data; +++ if (baselen > rx->skb->len) +++ return; +++ +++ ie = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, +++ mgmt->u.beacon.variable, +++ rx->skb->len - baselen); +++ if (ie && ie->datalen >= sizeof(struct ieee80211_he_operation) && +++ ie->datalen >= ieee80211_he_oper_size(ie->data + 1)) { +++ struct ieee80211_bss_conf *bss_conf = &rx->sdata->vif.bss_conf; +++ const struct ieee80211_he_operation *he_oper; +++ u8 color; +++ +++ he_oper = (void *)(ie->data + 1); +++ if (le32_get_bits(he_oper->he_oper_params, +++ IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED)) +++ return; +++ +++ color = le32_get_bits(he_oper->he_oper_params, +++ IEEE80211_HE_OPERATION_BSS_COLOR_MASK); +++ if (color == bss_conf->he_bss_color.color) +++ ieeee80211_obss_color_collision_notify(&rx->sdata->vif, +++ BIT_ULL(color)); +++ } +++} +++ ++ static ieee80211_rx_result debug_noinline ++ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) ++ { ++@@ -3205,6 +3248,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802 ++ !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { ++ int sig = 0; ++ +++ /* sw bss color collision detection */ +++ ieee80211_rx_check_bss_color_collision(rx); +++ ++ if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) && ++ !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) ++ sig = status->signal; diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-minstrel_ht-show-sampling-rates-in-debugfs.patch deleted file mode 100644 index 041ba31a37..0000000000 @@ -14433,6 +20763,203 @@ index a366a921d4..0000000000 - - max_gpr_tp_avg = minstrel_ht_get_tp_avg(mi, max_gpr_group, - max_gpr_idx, +diff --git a/package/kernel/mac80211/patches/subsys/360-mac80211-fix-a-memory-leak-where-sta_info-is-not-fre.patch b/package/kernel/mac80211/patches/subsys/360-mac80211-fix-a-memory-leak-where-sta_info-is-not-fre.patch +new file mode 100644 +index 0000000000..ff3cb7be53 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/360-mac80211-fix-a-memory-leak-where-sta_info-is-not-fre.patch +@@ -0,0 +1,77 @@ ++From 4db561ae4a90c2d0e15996634567559e292dc9e5 Mon Sep 17 00:00:00 2001 ++From: Ahmed Zaki <anzaki@gmail.com> ++Date: Sat, 2 Oct 2021 08:53:29 -0600 ++Subject: [PATCH] mac80211: fix a memory leak where sta_info is not freed ++ ++commit 8f9dcc29566626f683843ccac6113a12208315ca upstream. ++ ++The following is from a system that went OOM due to a memory leak: ++ ++wlan0: Allocated STA 74:83:c2:64:0b:87 ++wlan0: Allocated STA 74:83:c2:64:0b:87 ++wlan0: IBSS finish 74:83:c2:64:0b:87 (---from ieee80211_ibss_add_sta) ++wlan0: Adding new IBSS station 74:83:c2:64:0b:87 ++wlan0: moving STA 74:83:c2:64:0b:87 to state 2 ++wlan0: moving STA 74:83:c2:64:0b:87 to state 3 ++wlan0: Inserted STA 74:83:c2:64:0b:87 ++wlan0: IBSS finish 74:83:c2:64:0b:87 (---from ieee80211_ibss_work) ++wlan0: Adding new IBSS station 74:83:c2:64:0b:87 ++wlan0: moving STA 74:83:c2:64:0b:87 to state 2 ++wlan0: moving STA 74:83:c2:64:0b:87 to state 3 ++. ++. ++wlan0: expiring inactive not authorized STA 74:83:c2:64:0b:87 ++wlan0: moving STA 74:83:c2:64:0b:87 to state 2 ++wlan0: moving STA 74:83:c2:64:0b:87 to state 1 ++wlan0: Removed STA 74:83:c2:64:0b:87 ++wlan0: Destroyed STA 74:83:c2:64:0b:87 ++ ++The ieee80211_ibss_finish_sta() is called twice on the same STA from 2 ++different locations. On the second attempt, the allocated STA is not ++destroyed creating a kernel memory leak. ++ ++This is happening because sta_info_insert_finish() does not call ++sta_info_free() the second time when the STA already exists (returns ++-EEXIST). Note that the caller sta_info_insert_rcu() assumes STA is ++destroyed upon errors. ++ ++Same fix is applied to -ENOMEM. ++ ++Signed-off-by: Ahmed Zaki <anzaki@gmail.com> ++Link: https://lore.kernel.org/r/20211002145329.3125293-1-anzaki@gmail.com ++[change the error path label to use the existing code] ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++Signed-off-by: Viacheslav Sablin <sablin@ispras.ru> ++Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ++--- ++ net/mac80211/sta_info.c | 6 +++--- ++ 1 file changed, 3 insertions(+), 3 deletions(-) ++ ++--- a/net/mac80211/sta_info.c +++++ b/net/mac80211/sta_info.c ++@@ -646,13 +646,13 @@ static int sta_info_insert_finish(struct ++ /* check if STA exists already */ ++ if (sta_info_get_bss(sdata, sta->sta.addr)) { ++ err = -EEXIST; ++- goto out_err; +++ goto out_cleanup; ++ } ++ ++ sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL); ++ if (!sinfo) { ++ err = -ENOMEM; ++- goto out_err; +++ goto out_cleanup; ++ } ++ ++ local->num_sta++; ++@@ -708,8 +708,8 @@ static int sta_info_insert_finish(struct ++ out_drop_sta: ++ local->num_sta--; ++ synchronize_net(); +++ out_cleanup: ++ cleanup_single_sta(sta); ++- out_err: ++ mutex_unlock(&local->sta_mtx); ++ kfree(sinfo); ++ rcu_read_lock(); +diff --git a/package/kernel/mac80211/patches/subsys/361-wifi-mac80211-Don-t-finalize-CSA-in-IBSS-mode-if-sta.patch b/package/kernel/mac80211/patches/subsys/361-wifi-mac80211-Don-t-finalize-CSA-in-IBSS-mode-if-sta.patch +new file mode 100644 +index 0000000000..dd3e934c00 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/361-wifi-mac80211-Don-t-finalize-CSA-in-IBSS-mode-if-sta.patch +@@ -0,0 +1,47 @@ ++From 552ba102a6898630a7d16887f29e606d6fabe508 Mon Sep 17 00:00:00 2001 ++From: Siddh Raman Pant <code@siddh.me> ++Date: Sun, 14 Aug 2022 20:45:12 +0530 ++Subject: [PATCH] wifi: mac80211: Don't finalize CSA in IBSS mode if state is ++ disconnected ++ ++commit 15bc8966b6d3a5b9bfe4c9facfa02f2b69b1e5f0 upstream. ++ ++When we are not connected to a channel, sending channel "switch" ++announcement doesn't make any sense. ++ ++The BSS list is empty in that case. This causes the for loop in ++cfg80211_get_bss() to be bypassed, so the function returns NULL ++(check line 1424 of net/wireless/scan.c), causing the WARN_ON() ++in ieee80211_ibss_csa_beacon() to get triggered (check line 500 ++of net/mac80211/ibss.c), which was consequently reported on the ++syzkaller dashboard. ++ ++Thus, check if we have an existing connection before generating ++the CSA beacon in ieee80211_ibss_finish_csa(). ++ ++Cc: stable@vger.kernel.org ++Fixes: cd7760e62c2a ("mac80211: add support for CSA in IBSS mode") ++Link: https://syzkaller.appspot.com/bug?id=05603ef4ae8926761b678d2939a3b2ad28ab9ca6 ++Reported-by: syzbot+b6c9fe29aefe68e4ad34@syzkaller.appspotmail.com ++Signed-off-by: Siddh Raman Pant <code@siddh.me> ++Tested-by: syzbot+b6c9fe29aefe68e4ad34@syzkaller.appspotmail.com ++Link: https://lore.kernel.org/r/20220814151512.9985-1-code@siddh.me ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ++--- ++ net/mac80211/ibss.c | 4 ++++ ++ 1 file changed, 4 insertions(+) ++ ++--- a/net/mac80211/ibss.c +++++ b/net/mac80211/ibss.c ++@@ -534,6 +534,10 @@ int ieee80211_ibss_finish_csa(struct iee ++ ++ sdata_assert_lock(sdata); ++ +++ /* When not connected/joined, sending CSA doesn't make sense. */ +++ if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) +++ return -ENOLINK; +++ ++ /* update cfg80211 bss information with the new channel */ ++ if (!is_zero_ether_addr(ifibss->bssid)) { ++ cbss = cfg80211_get_bss(sdata->local->hw.wiphy, +diff --git a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch +new file mode 100644 +index 0000000000..0e58b61602 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch +@@ -0,0 +1,55 @@ ++From 5d20c6f932f2758078d0454729129c894fe353e7 Mon Sep 17 00:00:00 2001 ++From: Siddh Raman Pant <code@siddh.me> ++Date: Sat, 20 Aug 2022 01:33:40 +0530 ++Subject: [PATCH] wifi: mac80211: Fix UAF in ieee80211_scan_rx() ++ ++commit 60deb9f10eec5c6a20252ed36238b55d8b614a2c upstream. ++ ++ieee80211_scan_rx() tries to access scan_req->flags after a ++null check, but a UAF is observed when the scan is completed ++and __ieee80211_scan_completed() executes, which then calls ++cfg80211_scan_done() leading to the freeing of scan_req. ++ ++Since scan_req is rcu_dereference()'d, prevent the racing in ++__ieee80211_scan_completed() by ensuring that from mac80211's ++POV it is no longer accessed from an RCU read critical section ++before we call cfg80211_scan_done(). ++ ++Cc: stable@vger.kernel.org ++Link: https://syzkaller.appspot.com/bug?extid=f9acff9bf08a845f225d ++Reported-by: syzbot+f9acff9bf08a845f225d@syzkaller.appspotmail.com ++Suggested-by: Johannes Berg <johannes@sipsolutions.net> ++Signed-off-by: Siddh Raman Pant <code@siddh.me> ++Link: https://lore.kernel.org/r/20220819200340.34826-1-code@siddh.me ++Signed-off-by: Johannes Berg <johannes.berg@intel.com> ++Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ++--- ++ net/mac80211/scan.c | 11 +++++++---- ++ 1 file changed, 7 insertions(+), 4 deletions(-) ++ ++--- a/net/mac80211/scan.c +++++ b/net/mac80211/scan.c ++@@ -461,16 +461,19 @@ static void __ieee80211_scan_completed(s ++ scan_req = rcu_dereference_protected(local->scan_req, ++ lockdep_is_held(&local->mtx)); ++ ++- if (scan_req != local->int_scan_req) { ++- local->scan_info.aborted = aborted; ++- cfg80211_scan_done(scan_req, &local->scan_info); ++- } ++ RCU_INIT_POINTER(local->scan_req, NULL); ++ RCU_INIT_POINTER(local->scan_sdata, NULL); ++ ++ local->scanning = 0; ++ local->scan_chandef.chan = NULL; ++ +++ synchronize_rcu(); +++ +++ if (scan_req != local->int_scan_req) { +++ local->scan_info.aborted = aborted; +++ cfg80211_scan_done(scan_req, &local->scan_info); +++ } +++ ++ /* Set power back to normal operating levels. */ ++ ieee80211_hw_config(local, 0); ++ diff --git a/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch b/package/kernel/mac80211/patches/subsys/371-mac80211-don-t-apply-flow-control-on-management-fram.patch deleted file mode 100644 index 0d3b42f3b9..0000000000 @@ -19372,6 +25899,114 @@ index cd91a925f3..0000000000 - CALL_TXH(ieee80211_tx_h_michael_mic_add); - CALL_TXH(ieee80211_tx_h_sequence); - CALL_TXH(ieee80211_tx_h_fragment); +diff --git a/package/kernel/mac80211/patches/subsys/396-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch b/package/kernel/mac80211/patches/subsys/396-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch +deleted file mode 100644 +index 0fecd36382..0000000000 +--- a/package/kernel/mac80211/patches/subsys/396-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch ++++ /dev/null +@@ -1,52 +0,0 @@ +-From: Johannes Berg <johannes.berg@intel.com> +-Date: Wed, 5 Oct 2022 21:24:10 +0200 +-Subject: [PATCH] wifi: mac80211: fix crash in beacon protection for +- P2P-device +-MIME-Version: 1.0 +-Content-Type: text/plain; charset=UTF-8 +-Content-Transfer-Encoding: 8bit +- +-commit b2d03cabe2b2e150ff5a381731ea0355459be09f upstream. +- +-If beacon protection is active but the beacon cannot be +-decrypted or is otherwise malformed, we call the cfg80211 +-API to report this to userspace, but that uses a netdev +-pointer, which isn't present for P2P-Device. Fix this to +-call it only conditionally to ensure cfg80211 won't crash +-in the case of P2P-Device. +- +-This fixes CVE-2022-42722. +- +-Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de> +-Fixes: 9eaf183af741 ("mac80211: Report beacon protection failures to user space") +-Signed-off-by: Johannes Berg <johannes.berg@intel.com> +---- +- +---- a/net/mac80211/rx.c +-+++ b/net/mac80211/rx.c +-@@ -1972,10 +1972,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_ +- +- if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS || +- mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + +-- NUM_DEFAULT_BEACON_KEYS) { +-- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +-- skb->data, +-- skb->len); +-+ NUM_DEFAULT_BEACON_KEYS) { +-+ if (rx->sdata->dev) +-+ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +-+ skb->data, +-+ skb->len); +- return RX_DROP_MONITOR; /* unexpected BIP keyidx */ +- } +- +-@@ -2123,7 +2124,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_ +- /* either the frame has been decrypted or will be dropped */ +- status->flag |= RX_FLAG_DECRYPTED; +- +-- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE)) +-+ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE && +-+ rx->sdata->dev)) +- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +- skb->data, skb->len); +- +diff --git a/package/kernel/mac80211/patches/subsys/397-disable-mbssid.patch b/package/kernel/mac80211/patches/subsys/397-disable-mbssid.patch +deleted file mode 100644 +index 5bd33c4588..0000000000 +--- a/package/kernel/mac80211/patches/subsys/397-disable-mbssid.patch ++++ /dev/null +@@ -1,44 +0,0 @@ +---- a/net/mac80211/util.c +-+++ b/net/mac80211/util.c +-@@ -1406,6 +1406,7 @@ static size_t ieee802_11_find_bssid_prof +- if (!bss_bssid || !transmitter_bssid) +- return profile_len; +- +-+ return 0; +- for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { +- if (elem->datalen < 2) +- continue; +---- a/net/wireless/scan.c +-+++ b/net/wireless/scan.c +-@@ -1982,6 +1982,7 @@ static const struct element +- const struct element *next_mbssid; +- const struct element *next_sub; +- +-+ return NULL; +- next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, +- mbssid_end, +- ielen - (mbssid_end - ie)); +-@@ -2063,6 +2064,7 @@ static void cfg80211_parse_mbssid_data(s +- u16 capability; +- struct cfg80211_bss *bss; +- +-+ return; +- if (!non_tx_data) +- return; +- if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) +-@@ -2221,6 +2223,7 @@ cfg80211_update_notlisted_nontrans(struc +- const struct cfg80211_bss_ies *old; +- u8 cpy_len; +- +-+ return; +- lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); +- +- ie = mgmt->u.probe_resp.variable; +-@@ -2436,6 +2439,7 @@ cfg80211_inform_bss_frame_data(struct wi +- +- res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt, +- len, gfp); +-+ return res; +- if (!res || !wiphy->support_mbssid || +- !cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) +- return res; diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch index 974595e11a..f2ed528d23 100644 --- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch @@ -19386,7 +26021,7 @@ index 974595e11a..f2ed528d23 100644 return -EINVAL; diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch -index 6f13f64208..612b9d66ee 100644 +index 6f13f64208..50c24a7746 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -1,24 +1,24 @@ @@ -19461,7 +26096,7 @@ index 6f13f64208..612b9d66ee 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2769,6 +2769,19 @@ static int ieee80211_get_tx_power(struct -+@@ -2845,6 +2845,19 @@ static int ieee80211_get_tx_power(struct ++@@ -2812,6 +2812,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -19475,7 +26110,7 @@ index 6f13f64208..612b9d66ee 100644 { -@@ -4413,6 +4426,7 @@ const struct cfg80211_ops mac80211_confi + struct ieee80211_local *local = wiphy_priv(wiphy); -+@@ -4549,6 +4562,7 @@ const struct cfg80211_ops mac80211_confi ++@@ -4516,6 +4529,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -19487,7 +26122,7 @@ index 6f13f64208..612b9d66ee 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1435,6 +1435,7 @@ struct ieee80211_local { -+@@ -1464,6 +1464,7 @@ struct ieee80211_local { ++@@ -1448,6 +1448,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ @@ -19508,7 +26143,7 @@ index 6f13f64208..612b9d66ee 100644 - [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 }, - [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 }, - [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy), -+@@ -797,6 +797,7 @@ static const struct nla_policy nl80211_p ++@@ -802,6 +802,7 @@ static const struct nla_policy nl80211_p + NLA_POLICY_NESTED(nl80211_mbssid_config_policy), + [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, + [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, @@ -19517,7 +26152,7 @@ index 6f13f64208..612b9d66ee 100644 /* policy for the key attributes */ -@@ -3322,6 +3323,20 @@ static int nl80211_set_wiphy(struct sk_b -+@@ -3377,6 +3378,22 @@ static int nl80211_set_wiphy(struct sk_b ++@@ -3391,6 +3392,22 @@ static int nl80211_set_wiphy(struct sk_b if (result) - return result; + goto out; @@ -19581,6 +26216,73 @@ index 0000000000..26af6a2fb9 +-#endif /* < 5.2 */ +- +-#endif /* _BP_OF_NET_H */ +diff --git a/package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch b/package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch +new file mode 100644 +index 0000000000..dc2b05b1a3 +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch +@@ -0,0 +1,22 @@ ++--- a/include/uapi/linux/nl80211.h +++++ b/include/uapi/linux/nl80211.h ++@@ -6027,6 +6027,11 @@ enum nl80211_feature_flags { ++ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision ++ * detection and change announcemnts. ++ * +++ * @NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD: Driver running in AP mode supports +++ * FILS encryption and decryption for (Re)Association Request and Response +++ * frames. Userspace has to share FILS AAD details to the driver by using +++ * @NL80211_CMD_SET_FILS_AAD. +++ * ++ * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC ++ * detection. ++ * ++@@ -6095,6 +6100,7 @@ enum nl80211_ext_feature_index { ++ NL80211_EXT_FEATURE_SECURE_RTT, ++ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, ++ NL80211_EXT_FEATURE_BSS_COLOR, +++ NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD, ++ NL80211_EXT_FEATURE_RADAR_BACKGROUND, ++ ++ /* add new features before the definition below */ +diff --git a/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch b/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch +new file mode 100644 +index 0000000000..e7da94c9cd +--- /dev/null ++++ b/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch +@@ -0,0 +1,33 @@ ++From 313d8c18385f10957402b475f9b0c209ceab6c5a Mon Sep 17 00:00:00 2001 ++From: David Bauer <mail@david-bauer.net> ++Date: Fri, 8 Oct 2021 00:25:19 +0200 ++Subject: [PATCH] mac80211: mask nested A-MSDU support for mesh ++ ++mac80211 incorrectly processes A-MSDUs contained in A-MPDU frames. This ++results in dropped packets and severely impacted throughput. ++ ++As a workaround, don't indicate support for A-MSDUs contained in ++A-MPDUs. This improves throughput over mesh links by factor 10. ++ ++Ref: https://github.com/openwrt/mt76/issues/450 ++ ++Signed-off-by: David Bauer <mail@david-bauer.net> ++--- ++ net/mac80211/agg-rx.c | 4 +++- ++ 1 file changed, 3 insertions(+), 1 deletion(-) ++ ++--- a/net/mac80211/agg-rx.c +++++ b/net/mac80211/agg-rx.c ++@@ -251,7 +251,11 @@ static void ieee80211_send_addba_resp(st ++ mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; ++ mgmt->u.action.u.addba_resp.dialog_token = dialog_token; ++ ++- capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); +++ capab = 0; +++#ifdef CONFIG_MAC80211_MESH +++ if (!sta->mesh) +++#endif +++ capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); ++ capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK); ++ capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); ++ capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); diff --git a/package/kernel/mac80211/realtek.mk b/package/kernel/mac80211/realtek.mk index 75cb94d7b6..44c6c25b08 100644 --- a/package/kernel/mac80211/realtek.mk -- GitLab