From 2636d06404c24ec6c2ad8395ad1dc8d26875be7a Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 27 May 2021 13:25:03 +0200 Subject: [PATCH 01/44] mac80211: update to latest HEAD Signed-off-by: John Crispin --- package/kernel/mac80211/Makefile | 21 +- package/kernel/mac80211/ath.mk | 13 +- package/kernel/mac80211/broadcom.mk | 4 +- .../mac80211/files/lib/netifd/mac80211.sh | 36 - .../files/lib/netifd/wireless/mac80211.sh | 195 ++- .../mac80211/files/lib/wifi/mac80211.sh | 110 +- package/kernel/mac80211/mac80211.sh.diff | 58 + .../patches/ath/402-ath_regd_optional.patch | 2 +- ...itting-to-stations-in-dynamic-SMPS-m.patch | 49 - .../080-ath10k_thermal_config.patch | 2 +- ...21-ath10k_init_devices_synchronously.patch | 0 ...h10k-increase-rx-buffer-size-to-2048.patch | 2 +- .../930-ath10k_add_tpt_led_trigger.patch | 4 +- ...rolling-support-for-various-chipsets.patch | 4 +- ...75-ath10k-use-tpt-trigger-by-default.patch | 2 +- ...980-ath10k-fix-max-antenna-gain-unit.patch | 0 ...-power-reduction-for-US-regulatory-d.patch | 0 .../201-ath5k-WAR-for-AR71xx-PCI-bug.patch | 0 .../411-ath5k_allow_adhoc_and_ap.patch | 0 .../420-ath5k_disable_fast_cc.patch | 0 .../430-add_ath5k_platform.patch | 0 .../{ath => ath5k}/432-ath5k_add_pciids.patch | 0 .../440-ath5k_channel_bw_debugfs.patch | 0 ...w-reset-AHB-WMAC-interface-on-AR91xx.patch | 0 ..._hw-issue-external-reset-for-QCA955x.patch | 0 ...h9k-force-rx_clear-when-disabling-rx.patch | 0 ...erpret-requested-txpower-in-EIRP-dom.patch | 0 ...power-reduction-for-US-regulatory-do.patch | 0 .../401-ath9k_blink_default.patch | 0 .../410-ath9k_allow_adhoc_and_ap.patch | 0 ...abled-MFP-capability-unconditionally.patch | 0 .../500-ath9k_eeprom_debugfs.patch | 4 +- .../{ath => ath9k}/501-ath9k_ahb_init.patch | 0 .../510-ath9k_intr_mitigation_tweak.patch | 0 .../511-ath9k_reduce_rxbuf.patch | 0 .../512-ath9k_channelbw_debugfs.patch | 4 +- .../513-ath9k_add_pci_ids.patch | 0 .../{ath => ath9k}/530-ath9k_extra_leds.patch | 10 +- .../531-ath9k_extra_platform_leds.patch | 0 .../540-ath9k_reduce_ani_interval.patch | 0 .../542-ath9k_debugfs_diag.patch | 4 +- .../543-ath9k_entropy_from_adc.patch | 0 ...544-ath9k-ar933x-usb-hang-workaround.patch | 0 .../545-ath9k_ani_ws_detect.patch | 0 .../547-ath9k_led_defstate_fix.patch | 0 .../548-ath9k_enable_gpio_chip.patch | 4 +- .../549-ath9k_enable_gpio_buttons.patch | 2 +- .../550-ath9k-disable-bands-via-dt.patch | 0 .../551-ath9k_ubnt_uap_plus_hsr.patch | 4 +- .../552-ath9k-ahb_of.patch} | 2 +- .../553-ath9k_of_gpio_mask.patch | 0 ...-register-wiphy-s-during-module_init.patch | 10 - .../patches/build/001-fix_build.patch | 8 +- ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 2 +- ...940-mwl8k_init_devices_synchronously.patch | 4 +- .../602-rt2x00-introduce-rt2x00eeprom.patch | 2 +- ...ent-set_tim-by-update-beacon-content.patch | 118 ++ .../patches/subsys/010-sync-nl80211_h.patch | 297 ++++ .../100-remove-cryptoapi-dependencies.patch | 698 --------- .../patches/subsys/130-disable-fils.patch | 32 - ...aes-cmac-switch-to-shash-CMAC-driver.patch | 230 --- .../132-mac80211-remove-cmac-dependency.patch | 10 - .../subsys/150-disable_addr_notifier.patch | 6 +- .../mac80211/patches/subsys/210-ap_scan.patch | 2 +- ...ort-immediate-reconnect-request-hint.patch | 38 +- ...-driver-based-disconnect-with-reconn.patch | 34 +- ...port-to-configure-SAE-PWE-value-to-d.patch | 74 + ...-get_default_func-move-default-flow-.patch | 2 +- ...add-rx-decapsulation-offload-support.patch | 26 +- ...le-QoS-support-for-nl80211-ctrl-port.patch | 116 ++ ...320-mac80211_hwsim-add-6GHz-channels.patch | 123 ++ ...211_hwsim-make-6-GHz-channels-usable.patch | 74 + ...-remove-legacy-minstrel-rate-control.patch | 2 +- ...-minstrel_ht-fix-MINSTREL_FRAC-macro.patch | 21 + .../370-mac80211-fix-TXQ-AC-confusion.patch | 61 - ...pply-flow-control-on-management-fram.patch | 4 +- ...set-sk_pacing_shift-for-802.3-txpath.patch | 2 +- ...-Rx-timestamp-calculation-for-all-pr.patch | 2 +- ...c80211-fix-time-is-after-bug-in-mlme.patch | 31 - ...MPDU-session-check-from-minstrel_ht-.patch | 126 ++ ...eee80211_tx_h_rate_ctrl-when-dequeue.patch | 114 ++ ...te-control-support-for-encap-offload.patch | 119 ++ ...11-minstrel_ht-fix-sample-time-check.patch | 23 + ...iwlwifi-specific-workaround-that-bro.patch | 51 + ...rting-aggregation-sessions-on-mesh-i.patch | 112 ++ ...introduce-aql_enable-node-in-debugfs.patch | 111 ++ ...ange-struct-txq_info-for-fewer-holes.patch | 39 + ...to-a-virtual-time-based-airtime-sche.patch | 1277 +++++++++++++++++ ...bling-4-address-mode-on-a-sta-vif-af.patch | 72 + ...on-API-to-configure-SAR-power-limita.patch | 398 +++++ ...mac80211-add-ieee80211_set_sar_specs.patch | 51 + .../500-mac80211_configure_antenna_gain.patch | 24 +- 92 files changed, 3737 insertions(+), 1345 deletions(-) delete mode 100644 package/kernel/mac80211/files/lib/netifd/mac80211.sh create mode 100644 package/kernel/mac80211/mac80211.sh.diff delete mode 100644 package/kernel/mac80211/patches/ath/560-ath9k-fix-transmitting-to-stations-in-dynamic-SMPS-m.patch rename package/kernel/mac80211/patches/{ath => ath10k}/080-ath10k_thermal_config.patch (97%) rename package/kernel/mac80211/patches/{ath => ath10k}/921-ath10k_init_devices_synchronously.patch (100%) rename package/kernel/mac80211/patches/{ath => ath10k}/922-ath10k-increase-rx-buffer-size-to-2048.patch (96%) rename package/kernel/mac80211/patches/{ath => ath10k}/930-ath10k_add_tpt_led_trigger.patch (89%) rename package/kernel/mac80211/patches/{ath => ath10k}/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch (99%) rename package/kernel/mac80211/patches/{ath => ath10k}/975-ath10k-use-tpt-trigger-by-default.patch (96%) rename package/kernel/mac80211/patches/{ath => ath10k}/980-ath10k-fix-max-antenna-gain-unit.patch (100%) rename package/kernel/mac80211/patches/{ath => ath10k}/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch (100%) rename package/kernel/mac80211/patches/{ath => ath5k}/201-ath5k-WAR-for-AR71xx-PCI-bug.patch (100%) rename package/kernel/mac80211/patches/{ath => ath5k}/411-ath5k_allow_adhoc_and_ap.patch (100%) rename package/kernel/mac80211/patches/{ath => ath5k}/420-ath5k_disable_fast_cc.patch (100%) rename package/kernel/mac80211/patches/{ath => ath5k}/430-add_ath5k_platform.patch (100%) rename package/kernel/mac80211/patches/{ath => ath5k}/432-ath5k_add_pciids.patch (100%) rename package/kernel/mac80211/patches/{ath => ath5k}/440-ath5k_channel_bw_debugfs.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/351-ath9k_hw-issue-external-reset-for-QCA955x.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/354-ath9k-force-rx_clear-when-disabling-rx.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/401-ath9k_blink_default.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/410-ath9k_allow_adhoc_and_ap.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/450-ath9k-enabled-MFP-capability-unconditionally.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/500-ath9k_eeprom_debugfs.patch (92%) rename package/kernel/mac80211/patches/{ath => ath9k}/501-ath9k_ahb_init.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/510-ath9k_intr_mitigation_tweak.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/511-ath9k_reduce_rxbuf.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/512-ath9k_channelbw_debugfs.patch (96%) rename package/kernel/mac80211/patches/{ath => ath9k}/513-ath9k_add_pci_ids.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/530-ath9k_extra_leds.patch (95%) rename package/kernel/mac80211/patches/{ath => ath9k}/531-ath9k_extra_platform_leds.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/540-ath9k_reduce_ani_interval.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/542-ath9k_debugfs_diag.patch (96%) rename package/kernel/mac80211/patches/{ath => ath9k}/543-ath9k_entropy_from_adc.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/544-ath9k-ar933x-usb-hang-workaround.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/545-ath9k_ani_ws_detect.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/547-ath9k_led_defstate_fix.patch (100%) rename package/kernel/mac80211/patches/{ath => ath9k}/548-ath9k_enable_gpio_chip.patch (98%) rename package/kernel/mac80211/patches/{ath => ath9k}/549-ath9k_enable_gpio_buttons.patch (98%) rename package/kernel/mac80211/patches/{ath => ath9k}/550-ath9k-disable-bands-via-dt.patch (100%) 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} (99%) rename package/kernel/mac80211/patches/{ath => ath9k}/553-ath9k_of_gpio_mask.patch (100%) create mode 100644 package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch create 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 delete mode 100644 package/kernel/mac80211/patches/subsys/130-disable-fils.patch delete mode 100644 package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch delete mode 100644 package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch create mode 100644 package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch create mode 100644 package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch create mode 100644 package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch create mode 100644 package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch create mode 100644 package/kernel/mac80211/patches/subsys/353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch delete mode 100644 package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch delete mode 100644 package/kernel/mac80211/patches/subsys/374-mac80211-fix-time-is-after-bug-in-mlme.patch create mode 100644 package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch create mode 100644 package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch create mode 100644 package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch create mode 100644 package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch create mode 100644 package/kernel/mac80211/patches/subsys/378-mac80211-remove-iwlwifi-specific-workaround-that-bro.patch create mode 100644 package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch create mode 100644 package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch create mode 100644 package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch create mode 100644 package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch create mode 100644 package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch create mode 100644 package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch create mode 100644 package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index f6ad06452f..dd39c2d069 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=5.10.16-1 +PKG_VERSION:=5.10.42-1 PKG_RELEASE:=1 -PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.16/ -PKG_HASH:=12856db780c5023edc47e2d18486eb3346bb7c82f1f2fc48deb3b163142f7d2d +PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.42/ +PKG_HASH:=6876520105240844fdb32d1dcdf2bfdea291a37a96f16c892fda3776ba714fcb PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) @@ -98,7 +98,7 @@ PKG_CONFIG_DEPENDS += \ define KernelPackage/cfg80211 $(call KernelPackage/mac80211/Default) TITLE:=cfg80211 - wireless configuration API - DEPENDS+= +iw +wireless-regdb + DEPENDS+= +iw +iwinfo +wireless-regdb ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) FILES:= \ $(PKG_BUILD_DIR)/compat/compat.ko \ @@ -127,7 +127,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 - DEPENDS+= +kmod-cfg80211 +hostapd-common + DEPENDS+= +kmod-cfg80211 +kmod-crypto-cmac +kmod-crypto-ccm +kmod-crypto-gcm +hostapd-common KCONFIG:=\ CONFIG_AVERAGE=y FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko @@ -501,9 +501,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/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) $(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used) endef @@ -511,9 +516,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/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath5k,ath5k/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath9k,ath9k/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath10k,ath10k/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k,ath11k/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/) + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rtl,rtl/) endef define Build/Compile @@ -539,7 +549,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 - $(INSTALL_DATA) ./files/lib/netifd/mac80211.sh $(1)/lib/netifd $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless $(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 f209c95ba8..ba03ae11a6 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -34,7 +34,7 @@ ifdef CONFIG_PACKAGE_MAC80211_TRACING WIL6210_TRACING endif -config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS +config-$(call config_package,ath) += ATH_CARDS ATH_COMMON config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL @@ -42,11 +42,10 @@ config-$(CONFIG_PACKAGE_ATH_DYNACK) += ATH9K_DYNACK config-$(call config_package,ath9k) += ATH9K config-$(call config_package,ath9k-common) += ATH9K_COMMON config-$(call config_package,owl-loader) += ATH9K_PCI_NO_EEPROM -config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB config-$(CONFIG_TARGET_ath79) += ATH9K_AHB config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB config-$(CONFIG_PCI) += ATH9K_PCI -config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD +config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD ATH_REG_DYNAMIC_USER_REG_HINTS config-$(CONFIG_ATH9K_HWRNG) += ATH9K_HWRNG config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 @@ -126,7 +125,7 @@ endef define KernelPackage/ath $(call KernelPackage/mac80211/Default) TITLE:=Atheros common driver part - DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79||TARGET_ath25 +kmod-mac80211 + DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79||TARGET_ath25 +kmod-mac80211 FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko MENU:=1 endef @@ -191,7 +190,7 @@ define KernelPackage/ath9k-common TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k HIDDEN:=1 - DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath +@DRIVER_11N_SUPPORT + DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ath79 +kmod-ath +@DRIVER_11N_SUPPORT FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko @@ -201,7 +200,7 @@ define KernelPackage/ath9k $(call KernelPackage/mac80211/Default) TITLE:=Atheros 802.11n PCI wireless cards support URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k - DEPENDS+= @PCI_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath9k-common + DEPENDS+= @PCI_SUPPORT||TARGET_ath79 +kmod-ath9k-common FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko AUTOLOAD:=$(call AutoProbe,ath9k) @@ -231,7 +230,7 @@ define KernelPackage/ath9k/config config ATH9K_UBNTHSR bool "Support for Ubiquiti UniFi Outdoor+ access point" - depends on PACKAGE_kmod-ath9k && (TARGET_ar71xx_generic||TARGET_ath79) + depends on PACKAGE_kmod-ath9k && TARGET_ath79 default y endef diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk index fb576c5809..473bbf597c 100644 --- a/package/kernel/mac80211/broadcom.mk +++ b/package/kernel/mac80211/broadcom.mk @@ -209,7 +209,7 @@ config PACKAGE_B43_USE_BCMA default "16,28,29,30" if TARGET_bcm47xx_mips74k default "5,6,7,8,9,10,11,13,15,16,28,29,30" help - This is a comma seperated list of core revision numbers. + This is a comma separated list of core revision numbers. Example (keep files for rev5 only): 5 @@ -224,7 +224,7 @@ config PACKAGE_B43_USE_BCMA default "N,HT" if TARGET_bcm47xx_mips74k default "G,N,LP,HT" help - This is a comma seperated list of PHY types: + This is a comma separated list of PHY types: A => A-PHY AG => Dual A-PHY G-PHY G => G-PHY 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 --- a/package/kernel/mac80211/files/lib/netifd/mac80211.sh +++ /dev/null @@ -1,36 +0,0 @@ -mac80211_phy_to_path() { - local phy="$1" - - [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${phy} ] || return - - local path="$(readlink -f /sys/class/ieee80211/${phy}/device)" - [ -n "$path" ] || return - - path="${path##/sys/devices/}" - case "$path" in - platform*/pci*) path="${path##platform/}";; - esac - - local p - local seq="" - for p in $(ls /sys/class/ieee80211/$phy/device/ieee80211); do - [ "$p" = "$phy" ] && { - echo "$path${seq:++$seq}" - break - } - - seq=$((${seq:-0} + 1)) - done -} - -mac80211_path_to_phy() { - local path="$1" - - local p - for p in $(ls /sys/class/ieee80211); do - local cur="$(mac80211_phy_to_path "$p")" - case "$cur" in - *$path) echo "$p"; return;; - esac - done -} diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 92c56afd24..a58af1fef0 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 @@ #!/bin/sh . /lib/netifd/netifd-wireless.sh . /lib/netifd/hostapd.sh -. /lib/netifd/mac80211.sh init_wireless_driver "$@" @@ -26,11 +25,11 @@ drv_mac80211_init_device_config() { hostapd_common_add_device_config config_add_string path phy 'macaddr:macaddr' - config_add_string hwmode 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_int num_global_macaddr config_add_boolean noscan ht_coex acs_exclude_dfs config_add_array ht_capab config_add_array channels @@ -44,11 +43,24 @@ drv_mac80211_init_device_config() { su_beamformee \ mu_beamformer \ mu_beamformee \ + he_su_beamformer \ + he_su_beamformee \ + he_mu_beamformer \ vht_txop_ps \ htc_vht \ rx_antenna_pattern \ - tx_antenna_pattern - config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc + tx_antenna_pattern \ + he_spr_sr_control \ + he_twt_required + config_add_int \ + vht_max_a_mpdu_len_exp \ + vht_max_mpdu \ + vht_link_adapt \ + vht160 \ + rx_stbc \ + tx_stbc \ + he_bss_color \ + he_spr_non_srg_obss_pd_max_offset config_add_boolean \ ldpc \ greenfield \ @@ -96,6 +108,23 @@ mac80211_add_capabilities() { export -n -- "$__var=$__out" } +mac80211_add_he_capabilities() { + local __out= oifs + + oifs="$IFS" + IFS=: + for capab in "$@"; do + set -- $capab + [ "$(($4))" -gt 0 ] || continue + [ "$(((0x$2) & $3))" -gt 0 ] || { + eval "$1=0" + continue + } + append base_cfg "$1=1" "$N" + done + IFS="$oifs" +} + mac80211_hostapd_setup_base() { local phy="$1" @@ -119,6 +148,9 @@ mac80211_hostapd_setup_base() { [ "$noscan" -gt 0 ] && hostapd_noscan=1 [ "$tx_burst" = 0 ] && tx_burst= + chan_ofs=0 + [ "$band" = "6g" ] && chan_ofs=1 + ieee80211n=1 ht_capab= case "$htmode" in @@ -126,7 +158,7 @@ mac80211_hostapd_setup_base() { HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160) case "$hwmode" in a) - case "$(( ($channel / 4) % 2 ))" in + case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in 1) ht_capab="[HT40+]";; 0) ht_capab="[HT40-]";; esac @@ -200,7 +232,7 @@ mac80211_hostapd_setup_base() { case "$htmode" in VHT20|HE20) enable_ac=1;; VHT40|HE40) - case "$(( ($channel / 4) % 2 ))" in + case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in 1) idx=$(($channel + 2));; 0) idx=$(($channel - 2));; esac @@ -208,7 +240,7 @@ mac80211_hostapd_setup_base() { vht_center_seg0=$idx ;; VHT80|HE80) - case "$(( ($channel / 4) % 4 ))" in + case "$(( (($channel / 4) + $chan_ofs) % 4 ))" in 1) idx=$(($channel + 6));; 2) idx=$(($channel + 2));; 3) idx=$(($channel - 2));; @@ -219,15 +251,35 @@ mac80211_hostapd_setup_base() { vht_center_seg0=$idx ;; VHT160|HE160) - case "$channel" in - 36|40|44|48|52|56|60|64) idx=50;; - 100|104|108|112|116|120|124|128) idx=114;; - esac + if [ "$band" = "6g" ]; then + case "$channel" in + 1|5|9|13|17|21|25|29) idx=15;; + 33|37|41|45|49|53|57|61) idx=47;; + 65|69|73|77|81|85|89|93) idx=79;; + 97|101|105|109|113|117|121|125) idx=111;; + 129|133|137|141|145|149|153|157) idx=143;; + 161|165|169|173|177|181|185|189) idx=175;; + 193|197|201|205|209|213|217|221) idx=207;; + esac + else + case "$channel" in + 36|40|44|48|52|56|60|64) idx=50;; + 100|104|108|112|116|120|124|128) idx=114;; + esac + fi enable_ac=1 vht_oper_chwidth=2 vht_center_seg0=$idx ;; esac + [ "$band" = "6g" ] && { + op_class= + case "$htmode" in + HE20) op_class=131;; + HE*) op_class=$((132 + $vht_oper_chwidth)) + esac + [ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N" + } [ "$hwmode" = "a" ] || enable_ac=0 if [ "$enable_ac" != "0" ]; then @@ -337,16 +389,62 @@ mac80211_hostapd_setup_base() { esac if [ "$enable_ax" != "0" ]; then + json_get_vars \ + he_su_beamformer:1 \ + he_su_beamformee:0 \ + he_mu_beamformer:1 \ + he_twt_required:0 \ + he_spr_sr_control:0 \ + 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=${he_phy_cap:2} + he_mac_cap=$(iw phy "$phy" info | 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" } + + 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 \ + he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \ + he_spr_sr_control:${he_phy_cap:14:2}:0x1:$he_spr_sr_control \ + he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required + + [ "$he_spr_sr_control" -gt 0 ] && append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" + append base_cfg "he_default_pe_duration=4" "$N" append base_cfg "he_rts_threshold=1023" "$N" - append base_cfg "he_su_beamformer=1" "$N" - append base_cfg "he_su_beamformee=1" "$N" - append base_cfg "he_mu_beamformer=1" "$N" + append base_cfg "he_mu_edca_qos_info_param_count=0" "$N" + append base_cfg "he_mu_edca_qos_info_q_ack=0" "$N" + append base_cfg "he_mu_edca_qos_info_queue_request=0" "$N" + append base_cfg "he_mu_edca_qos_info_txop_request=0" "$N" + append base_cfg "he_mu_edca_ac_be_aifsn=8" "$N" + append base_cfg "he_mu_edca_ac_be_aci=0" "$N" + append base_cfg "he_mu_edca_ac_be_ecwmin=9" "$N" + append base_cfg "he_mu_edca_ac_be_ecwmax=10" "$N" + append base_cfg "he_mu_edca_ac_be_timer=255" "$N" + append base_cfg "he_mu_edca_ac_bk_aifsn=15" "$N" + append base_cfg "he_mu_edca_ac_bk_aci=1" "$N" + append base_cfg "he_mu_edca_ac_bk_ecwmin=9" "$N" + append base_cfg "he_mu_edca_ac_bk_ecwmax=10" "$N" + append base_cfg "he_mu_edca_ac_bk_timer=255" "$N" + append base_cfg "he_mu_edca_ac_vi_ecwmin=5" "$N" + append base_cfg "he_mu_edca_ac_vi_ecwmax=7" "$N" + append base_cfg "he_mu_edca_ac_vi_aifsn=5" "$N" + append base_cfg "he_mu_edca_ac_vi_aci=2" "$N" + append base_cfg "he_mu_edca_ac_vi_timer=255" "$N" + append base_cfg "he_mu_edca_ac_vo_aifsn=5" "$N" + append base_cfg "he_mu_edca_ac_vo_aci=3" "$N" + append base_cfg "he_mu_edca_ac_vo_ecwmin=5" "$N" + append base_cfg "he_mu_edca_ac_vo_ecwmax=7" "$N" + append base_cfg "he_mu_edca_ac_vo_timer=255" "$N" fi hostapd_prepare_device_config "$hostapd_conf_file" nl80211 @@ -426,7 +524,11 @@ mac80211_generate_mac() { local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS" macidx=$(($id + 1)) - [ "$((0x$mask1))" -gt 0 ] && { + + local use_global=0 + [ "$id" -gt 0 -a "$macidx" -le "$num_global_macaddr" ] && use_global=1 + + [ "$((0x$mask1))" -gt 0 -a "$use_global" -lt 1 ] && { b1="0x$1" [ "$id" -gt 0 ] && \ b1=$(($b1 ^ ((($id - !($b1 & 2)) << 2)) | 0x2)) @@ -434,7 +536,7 @@ mac80211_generate_mac() { return } - [ "$((0x$mask6))" -lt 255 ] && { + [ "$((0x$mask6))" -lt 255 -a "$use_global" -gt 0 ] && { printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id )) return } @@ -449,7 +551,7 @@ mac80211_generate_mac() { find_phy() { [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 [ -n "$path" ] && { - phy="$(mac80211_path_to_phy "$path")" + phy="$(iwinfo nl80211 phyname "path=$path")" [ -n "$phy" ] && return 0 } [ -n "$macaddr" ] && { @@ -689,14 +791,8 @@ mac80211_prepare_iw_htmode() { case "$htmode" in VHT20|HT20) iw_htmode=HT20;; HT40*|VHT40|VHT160) - case "$hwmode" in - a) - case "$(( ($channel / 4) % 2 ))" in - 1) iw_htmode="HT40+" ;; - 0) iw_htmode="HT40-";; - esac - ;; - *) + case "$band" in + 2g) case "$htmode" in HT40+) iw_htmode="HT40+";; HT40-) iw_htmode="HT40-";; @@ -709,6 +805,12 @@ mac80211_prepare_iw_htmode() { ;; esac ;; + *) + case "$(( ($channel / 4) % 2 ))" in + 1) iw_htmode="HT40+" ;; + 0) iw_htmode="HT40-";; + esac + ;; esac [ "$auto_channel" -gt 0 ] && iw_htmode="HT40+" ;; @@ -818,7 +920,6 @@ mac80211_setup_vif() { mesh) wireless_vif_parse_encryption [ -z "$htmode" ] && htmode="NOHT"; - freq="$(get_freq "$phy" "$channel")" if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then mac80211_setup_supplicant $vif_enable || failed=1 else @@ -832,7 +933,6 @@ mac80211_setup_vif() { adhoc) wireless_vif_parse_encryption if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then - freq="$(get_freq "$phy" "$channel")" mac80211_setup_supplicant_noctl $vif_enable || failed=1 else mac80211_setup_adhoc $vif_enable @@ -849,10 +949,30 @@ mac80211_setup_vif() { get_freq() { local phy="$1" - local chan="$2" - iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}' + local channel="$2" + local band="$3" + + case "$band" in + 2g) band="1:";; + 5g) band="2:";; + 60g) band="3:";; + 6g) band="4:";; + esac + + iw "$phy" info | awk -v band="$band" -v channel="[$channel]" ' + +$1 ~ /Band/ { + band_match = band == $2 +} + +band_match && $3 == "MHz" && $4 == channel { + print $2 + exit +} +' } + chan_is_dfs() { local phy="$1" local chan="$2" @@ -896,7 +1016,8 @@ drv_mac80211_setup() { country chanbw distance \ txpower antenna_gain \ rxantenna txantenna \ - frag rts beacon_int:100 htmode + frag rts beacon_int:100 htmode \ + num_global_macaddr json_get_values basic_rate_list basic_rate json_get_values scan_list scan_list json_select .. @@ -907,10 +1028,8 @@ drv_mac80211_setup() { return 1 } - [ -z "$(uci -q -P /var/state show wireless._${phy})" ] && { - uci -q -P /var/state set wireless._${phy}=phy - wireless_set_data phy="$phy" - } + wireless_set_data phy="$phy" + [ -z "$(uci -q -P /var/state show wireless._${phy})" ] && uci -q -P /var/state set wireless._${phy}=phy OLDAPLIST=$(uci -q -P /var/state get wireless._${phy}.aplist) OLDSPLIST=$(uci -q -P /var/state get wireless._${phy}.splist) @@ -935,7 +1054,7 @@ drv_mac80211_setup() { done # convert channel to frequency - [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")" + [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")" [ -n "$country" ] && { iw reg get | grep -q "^country $country:" || { @@ -960,6 +1079,7 @@ drv_mac80211_setup() { set_default txantenna 0xffffffff set_default distance 0 set_default antenna_gain 0 + set_default num_global_macaddr 1 [ "$txantenna" = "all" ] && txantenna=0xffffffff [ "$rxantenna" = "all" ] && rxantenna=0xffffffff @@ -1003,6 +1123,7 @@ drv_mac80211_setup() { [ -n "$hostapd_ctrl" ] && { local no_reload=1 if [ -n "$(ubus list | grep hostapd.$primary_ap)" ]; then + no_reload=0 [ "${NEW_MD5}" = "${OLD_MD5}" ] || { ubus call hostapd.$primary_ap reload no_reload=$? @@ -1077,6 +1198,10 @@ drv_mac80211_teardown() { json_select data json_get_vars phy json_select .. + [ -n "$phy" ] || { + echo "Bug: PHY is undefined for device '$1'" + return 1 + } mac80211_interface_cleanup "$phy" uci -q -P /var/state revert wireless._${phy} diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index 3e99f06693..6aa46b0c74 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -1,5 +1,4 @@ #!/bin/sh -. /lib/netifd/mac80211.sh append DRIVERS "mac80211" @@ -11,7 +10,7 @@ lookup_phy() { local devpath config_get devpath "$device" path [ -n "$devpath" ] && { - phy="$(mac80211_path_to_phy "$devpath")" + phy="$(iwinfo nl80211 phyname "path=$devpath")" [ -n "$phy" ] && return } @@ -57,6 +56,85 @@ check_mac80211_device() { [ "$phy" = "$dev" ] && found=1 } + +__get_band_defaults() { + local phy="$1" + + ( iw phy "$phy" info; echo ) | awk ' +BEGIN { + bands = "" +} + +($1 == "Band" || $1 == "") && band { + if (channel) { + mode="NOHT" + if (ht) mode="HT20" + if (vht && band != "1:") mode="VHT80" + if (he) mode="HE80" + if (he && band == "1:") mode="HE20" + sub("\\[", "", channel) + sub("\\]", "", channel) + bands = bands band channel ":" mode " " + } + band="" +} + +$1 == "Band" { + band = $2 + channel = "" + vht = "" + ht = "" + he = "" +} + +$0 ~ "Capabilities:" { + ht=1 +} + +$0 ~ "VHT Capabilities" { + vht=1 +} + +$0 ~ "HE Iftypes" { + he=1 +} + +$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel { + channel = $4 +} + +END { + print bands +}' +} + +get_band_defaults() { + local phy="$1" + + for c in $(__get_band_defaults "$phy"); do + local band="${c%%:*}" + c="${c#*:}" + local chan="${c%%:*}" + c="${c#*:}" + local mode="${c%%:*}" + + case "$band" in + 1) band=2g;; + 2) band=5g;; + 3) band=60g;; + 4) band=6g;; + *) band="";; + esac + + [ -n "$band" ] || continue + [ -n "$mode_band" -a "$band" = "6g" ] && return + + mode_band="$band" + channel="$chan" + htmode="$mode" + done +} + detect_mac80211() { devidx=0 config_load wireless @@ -75,28 +153,14 @@ detect_mac80211() { config_foreach check_mac80211_device wifi-device [ "$found" -gt 0 ] && continue - mode_band="g" - channel="11" + mode_band="" + channel="" htmode="" ht_capab="" - iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20 - - iw phy "$dev" info | grep -q '\* 5... MHz \[' && { - mode_band="a" - channel=$(iw phy "$dev" info | grep '\* 5... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\].*//g') - iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80" - } - - iw phy "$dev" info | grep -q '\* 5.... MHz \[' && { - mode_band="ad" - channel=$(iw phy "$dev" info | grep '\* 5.... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\|\].*//g') - iw phy "$dev" info | grep -q 'Capabilities:' && htmode="HT20" - } + get_band_defaults "$dev" - [ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode" - - path="$(mac80211_phy_to_path "$dev")" + path="$(iwinfo nl80211 path "$dev")" if [ -n "$path" ]; then dev_id="set wireless.radio${devidx}.path='$path'" else @@ -106,10 +170,10 @@ detect_mac80211() { uci -q batch <<-EOF set wireless.radio${devidx}=wifi-device set wireless.radio${devidx}.type=mac80211 - set wireless.radio${devidx}.channel=${channel} - set wireless.radio${devidx}.hwmode=11${mode_band} ${dev_id} - ${ht_capab} + set wireless.radio${devidx}.channel=${channel} + set wireless.radio${devidx}.band=${mode_band} + set wireless.radio${devidx}.htmode=$htmode set wireless.radio${devidx}.disabled=1 set wireless.default_radio${devidx}=wifi-iface diff --git a/package/kernel/mac80211/mac80211.sh.diff b/package/kernel/mac80211/mac80211.sh.diff new file mode 100644 index 0000000000..2fb6d472b3 --- /dev/null +++ b/package/kernel/mac80211/mac80211.sh.diff @@ -0,0 +1,58 @@ +--- mac80211.sh 2021-06-05 15:10:48.522323044 +0200 ++++ mac80211.new 2021-06-08 10:09:52.652540350 +0200 +@@ -1036,13 +1036,6 @@ + local found + + for wdev in $(list_phy_interfaces "$phy"); do +- found=0 +- for cwdev in $OLDAPLIST $OLDSPLIST $OLDUMLIST; do +- if [ "$wdev" = "$cwdev" ]; then +- found=1 +- break +- fi +- done + if [ "$found" = "0" ]; then + ip link set dev "$wdev" down + iw dev "$wdev" del +@@ -1107,33 +1100,24 @@ + for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif + NEWAPLIST= + for_each_interface "ap" mac80211_prepare_vif +- NEW_MD5=$(test -e "${hostapd_conf_file}" && md5sum ${hostapd_conf_file}) +- OLD_MD5=$(uci -q -P /var/state get wireless._${phy}.md5) +- if [ "${NEWAPLIST}" != "${OLDAPLIST}" ]; then +- mac80211_vap_cleanup hostapd "${OLDAPLIST}" +- fi ++ mac80211_vap_cleanup hostapd "${OLDAPLIST}" + [ -n "${NEWAPLIST}" ] && mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap + local add_ap=0 + local primary_ap=${NEWAPLIST%% *} + [ -n "$hostapd_ctrl" ] && { + local no_reload=1 + if [ -n "$(ubus list | grep hostapd.$primary_ap)" ]; then +- [ "${NEW_MD5}" = "${OLD_MD5}" ] || { +- ubus call hostapd.$primary_ap reload +- no_reload=$? +- if [ "$no_reload" != "0" ]; then +- mac80211_vap_cleanup hostapd "${OLDAPLIST}" +- mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" +- mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" +- sleep 2 +- mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap +- for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif +- fi +- } ++ mac80211_vap_cleanup hostapd "${OLDAPLIST}" ++ mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)" ++ mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)" ++ sleep 2 ++ mac80211_iw_interface_add "$phy" "${NEWAPLIST%% *}" __ap ++ for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif + fi + if [ "$no_reload" != "0" ]; then + add_ap=1 + ubus wait_for hostapd ++ ip link set $primary_ap down + local hostapd_res="$(ubus call hostapd config_add "{\"iface\":\"$primary_ap\", \"config\":\"${hostapd_conf_file}\"}")" + ret="$?" + [ "$ret" != 0 -o -z "$hostapd_res" ] && { 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..3c9180b113 100644 --- a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch +++ b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch @@ -82,7 +82,7 @@ help --- a/local-symbols +++ b/local-symbols -@@ -85,6 +85,7 @@ ADM8211= +@@ -86,6 +86,7 @@ ADM8211= ATH_COMMON= WLAN_VENDOR_ATH= ATH_DEBUG= diff --git a/package/kernel/mac80211/patches/ath/560-ath9k-fix-transmitting-to-stations-in-dynamic-SMPS-m.patch b/package/kernel/mac80211/patches/ath/560-ath9k-fix-transmitting-to-stations-in-dynamic-SMPS-m.patch deleted file mode 100644 index 68f3a31548..0000000000 --- a/package/kernel/mac80211/patches/ath/560-ath9k-fix-transmitting-to-stations-in-dynamic-SMPS-m.patch +++ /dev/null @@ -1,49 +0,0 @@ -From: Felix Fietkau -Date: Sun, 14 Feb 2021 19:45:50 +0100 -Subject: [PATCH] ath9k: fix transmitting to stations in dynamic SMPS mode - -When transmitting to a receiver in dynamic SMPS mode, all transmissions that -use multiple spatial streams need to be sent using CTS-to-self or RTS/CTS to -give the receiver's extra chains some time to wake up. -This fixes the tx rate getting stuck at <= MCS7 for some clients, especially -Intel ones, which make aggressive use of SMPS. - -Cc: stable@vger.kernel.org -Reported-by: Martin Kennedy -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -179,7 +179,8 @@ struct ath_frame_info { - s8 txq; - u8 keyix; - u8 rtscts_rate; -- u8 retries : 7; -+ u8 retries : 6; -+ u8 dyn_smps : 1; - u8 baw_tracked : 1; - u8 tx_power; - enum ath9k_key_type keytype:2; ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1271,6 +1271,11 @@ static void ath_buf_set_rate(struct ath_ - is_40, is_sgi, is_sp); - if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) - info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; -+ if (rix >= 8 && fi->dyn_smps) { -+ info->rates[i].RateFlags |= -+ ATH9K_RATESERIES_RTS_CTS; -+ info->flags |= ATH9K_TXDESC_CTSENA; -+ } - - info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, - is_40, false); -@@ -2114,6 +2119,7 @@ static void setup_frame_info(struct ieee - fi->keyix = an->ps_key; - else - fi->keyix = ATH9K_TXKEYIX_INVALID; -+ fi->dyn_smps = sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC; - fi->keytype = keytype; - fi->framelen = framelen; - fi->tx_power = txpower; 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 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..9ce44fd288 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= +@@ -145,6 +145,7 @@ ATH10K_SNOC= ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= diff --git a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath10k/921-ath10k_init_devices_synchronously.patch similarity index 100% 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 diff --git a/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch b/package/kernel/mac80211/patches/ath10k/922-ath10k-increase-rx-buffer-size-to-2048.patch similarity index 96% rename from package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch rename to package/kernel/mac80211/patches/ath10k/922-ath10k-increase-rx-buffer-size-to-2048.patch index abce361673..8f7a60eec8 100644 --- a/package/kernel/mac80211/patches/ath/922-ath10k-increase-rx-buffer-size-to-2048.patch +++ b/package/kernel/mac80211/patches/ath10k/922-ath10k-increase-rx-buffer-size-to-2048.patch @@ -26,7 +26,7 @@ Forwarded: https://patchwork.kernel.org/patch/11367055/ --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h -@@ -2242,7 +2242,7 @@ struct htt_rx_chan_info { +@@ -2243,7 +2243,7 @@ struct htt_rx_chan_info { * Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size, * rounded up to a cache line size. */ diff --git 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 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 1fedd337ac..74b3292e0c 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 -@@ -9713,6 +9713,21 @@ static int ath10k_mac_init_rd(struct ath +@@ -9708,6 +9708,21 @@ static int ath10k_mac_init_rd(struct ath return 0; } @@ -22,7 +22,7 @@ int ath10k_mac_register(struct ath10k *ar) { static const u32 cipher_suites[] = { -@@ -10062,6 +10077,12 @@ int ath10k_mac_register(struct ath10k *a +@@ -10057,6 +10072,12 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; diff --git 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 similarity index 99% 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 ab7cb669bb..fa007e73a1 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 @@ -114,7 +114,7 @@ v13: ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o --- a/local-symbols +++ b/local-symbols -@@ -145,6 +145,7 @@ ATH10K_DEBUG= +@@ -146,6 +146,7 @@ ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= ATH10K_THERMAL= @@ -456,7 +456,7 @@ v13: { --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -@@ -4585,6 +4585,8 @@ static const struct wmi_ops wmi_tlv_ops +@@ -4594,6 +4594,8 @@ static const struct wmi_ops wmi_tlv_ops .gen_echo = ath10k_wmi_tlv_op_gen_echo, .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, diff --git 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 similarity index 96% 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 f7569df33c..6da7bfa725 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 @@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin if (ret) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -10079,7 +10079,7 @@ int ath10k_mac_register(struct ath10k *a +@@ -10074,7 +10074,7 @@ int ath10k_mac_register(struct ath10k *a ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; #ifdef CPTCFG_MAC80211_LEDS diff --git a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch b/package/kernel/mac80211/patches/ath10k/980-ath10k-fix-max-antenna-gain-unit.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch rename to package/kernel/mac80211/patches/ath10k/980-ath10k-fix-max-antenna-gain-unit.patch diff --git a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch rename to package/kernel/mac80211/patches/ath10k/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch diff --git a/package/kernel/mac80211/patches/ath/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/201-ath5k-WAR-for-AR71xx-PCI-bug.patch rename to package/kernel/mac80211/patches/ath5k/201-ath5k-WAR-for-AR71xx-PCI-bug.patch diff --git a/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch rename to package/kernel/mac80211/patches/ath5k/411-ath5k_allow_adhoc_and_ap.patch diff --git a/package/kernel/mac80211/patches/ath/420-ath5k_disable_fast_cc.patch b/package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/420-ath5k_disable_fast_cc.patch rename to package/kernel/mac80211/patches/ath5k/420-ath5k_disable_fast_cc.patch diff --git a/package/kernel/mac80211/patches/ath/430-add_ath5k_platform.patch b/package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/430-add_ath5k_platform.patch rename to package/kernel/mac80211/patches/ath5k/430-add_ath5k_platform.patch diff --git a/package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch b/package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/432-ath5k_add_pciids.patch rename to package/kernel/mac80211/patches/ath5k/432-ath5k_add_pciids.patch diff --git a/package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch b/package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/440-ath5k_channel_bw_debugfs.patch rename to package/kernel/mac80211/patches/ath5k/440-ath5k_channel_bw_debugfs.patch diff --git a/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch rename to package/kernel/mac80211/patches/ath9k/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch diff --git a/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch rename to package/kernel/mac80211/patches/ath9k/351-ath9k_hw-issue-external-reset-for-QCA955x.patch diff --git a/package/kernel/mac80211/patches/ath/354-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/354-ath9k-force-rx_clear-when-disabling-rx.patch rename to package/kernel/mac80211/patches/ath9k/354-ath9k-force-rx_clear-when-disabling-rx.patch diff --git a/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch rename to package/kernel/mac80211/patches/ath9k/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch diff --git a/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch rename to package/kernel/mac80211/patches/ath9k/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch diff --git a/package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch b/package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/401-ath9k_blink_default.patch rename to package/kernel/mac80211/patches/ath9k/401-ath9k_blink_default.patch diff --git a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch rename to package/kernel/mac80211/patches/ath9k/410-ath9k_allow_adhoc_and_ap.patch diff --git a/package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch b/package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/450-ath9k-enabled-MFP-capability-unconditionally.patch rename to package/kernel/mac80211/patches/ath9k/450-ath9k-enabled-MFP-capability-unconditionally.patch diff --git a/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch similarity index 92% rename from package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch rename to package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch index 786a3ed3fb..48ccc81308 100644 --- a/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch +++ b/package/kernel/mac80211/patches/ath9k/500-ath9k_eeprom_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1361,6 +1361,53 @@ void ath9k_deinit_debug(struct ath_softc +@@ -1364,6 +1364,53 @@ void ath9k_deinit_debug(struct ath_softc ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); } @@ -54,7 +54,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1380,6 +1427,8 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1383,6 +1430,8 @@ int ath9k_init_debug(struct ath_hw *ah) ath9k_tx99_init_debug(sc); ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); diff --git a/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch rename to package/kernel/mac80211/patches/ath9k/501-ath9k_ahb_init.patch diff --git a/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch rename to package/kernel/mac80211/patches/ath9k/510-ath9k_intr_mitigation_tweak.patch diff --git a/package/kernel/mac80211/patches/ath/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/511-ath9k_reduce_rxbuf.patch rename to package/kernel/mac80211/patches/ath9k/511-ath9k_reduce_rxbuf.patch diff --git a/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch similarity index 96% rename from package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch rename to package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch index 80e33182f7..126d1d5c62 100644 --- a/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch +++ b/package/kernel/mac80211/patches/ath9k/512-ath9k_channelbw_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1408,6 +1408,52 @@ static const struct file_operations fops +@@ -1411,6 +1411,52 @@ static const struct file_operations fops .owner = THIS_MODULE }; @@ -53,7 +53,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1429,6 +1475,8 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1432,6 +1478,8 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_eeprom); diff --git a/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch rename to package/kernel/mac80211/patches/ath9k/513-ath9k_add_pci_ids.patch diff --git a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch similarity index 95% rename from package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch rename to package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch index 1f19483064..5fd5c73a2f 100644 --- a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/ath9k/530-ath9k_extra_leds.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -843,6 +843,9 @@ static inline int ath9k_dump_btcoex(stru +@@ -844,6 +844,9 @@ static inline int ath9k_dump_btcoex(stru #ifdef CPTCFG_MAC80211_LEDS void ath_init_leds(struct ath_softc *sc); void ath_deinit_leds(struct ath_softc *sc); @@ -10,7 +10,7 @@ #else static inline void ath_init_leds(struct ath_softc *sc) { -@@ -979,6 +982,13 @@ void ath_ant_comb_scan(struct ath_softc +@@ -980,6 +983,13 @@ void ath_ant_comb_scan(struct ath_softc #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ @@ -24,7 +24,7 @@ struct ath_softc { struct ieee80211_hw *hw; struct device *dev; -@@ -1032,9 +1042,8 @@ struct ath_softc { +@@ -1033,9 +1043,8 @@ struct ath_softc { spinlock_t chan_lock; #ifdef CPTCFG_MAC80211_LEDS @@ -192,7 +192,7 @@ #endif --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1453,6 +1453,61 @@ static const struct file_operations fops +@@ -1456,6 +1456,61 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -254,7 +254,7 @@ int ath9k_init_debug(struct ath_hw *ah) { -@@ -1477,6 +1532,10 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1480,6 +1535,10 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_eeprom); debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_chanbw); diff --git a/package/kernel/mac80211/patches/ath/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/531-ath9k_extra_platform_leds.patch rename to package/kernel/mac80211/patches/ath9k/531-ath9k_extra_platform_leds.patch diff --git a/package/kernel/mac80211/patches/ath/540-ath9k_reduce_ani_interval.patch b/package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/540-ath9k_reduce_ani_interval.patch rename to package/kernel/mac80211/patches/ath9k/540-ath9k_reduce_ani_interval.patch diff --git a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch similarity index 96% rename from package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch rename to package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch index 76cb63a5c8..f93a6fe5cd 100644 --- a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch +++ b/package/kernel/mac80211/patches/ath9k/542-ath9k_debugfs_diag.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1509,6 +1509,50 @@ static const struct file_operations fops +@@ -1512,6 +1512,50 @@ static const struct file_operations fops #endif @@ -51,7 +51,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1536,6 +1580,8 @@ int ath9k_init_debug(struct ath_hw *ah) +@@ -1539,6 +1583,8 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("gpio_led", S_IWUSR, sc->debug.debugfs_phy, sc, &fops_gpio_led); #endif diff --git a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch rename to package/kernel/mac80211/patches/ath9k/543-ath9k_entropy_from_adc.patch diff --git a/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch rename to package/kernel/mac80211/patches/ath9k/544-ath9k-ar933x-usb-hang-workaround.patch diff --git a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch rename to package/kernel/mac80211/patches/ath9k/545-ath9k_ani_ws_detect.patch diff --git a/package/kernel/mac80211/patches/ath/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/547-ath9k_led_defstate_fix.patch rename to package/kernel/mac80211/patches/ath9k/547-ath9k_led_defstate_fix.patch diff --git a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch similarity index 98% rename from package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch rename to package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch index 78206d2860..88198a4562 100644 --- a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch +++ b/package/kernel/mac80211/patches/ath9k/548-ath9k_enable_gpio_chip.patch @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau #include "common.h" #include "debug.h" -@@ -989,6 +990,14 @@ struct ath_led { +@@ -990,6 +991,14 @@ struct ath_led { struct led_classdev cdev; }; @@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau struct ath_softc { struct ieee80211_hw *hw; struct device *dev; -@@ -1044,6 +1053,9 @@ struct ath_softc { +@@ -1045,6 +1054,9 @@ struct ath_softc { #ifdef CPTCFG_MAC80211_LEDS const char *led_default_trigger; struct list_head leds; diff --git a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch similarity index 98% rename from package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch rename to package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch index 716e09f351..83076b8ae4 100644 --- a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch +++ b/package/kernel/mac80211/patches/ath9k/549-ath9k_enable_gpio_buttons.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -1055,6 +1055,7 @@ struct ath_softc { +@@ -1056,6 +1056,7 @@ struct ath_softc { struct list_head leds; #ifdef CONFIG_GPIOLIB struct ath9k_gpio_chip *gpiochip; diff --git a/package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch b/package/kernel/mac80211/patches/ath9k/550-ath9k-disable-bands-via-dt.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/550-ath9k-disable-bands-via-dt.patch rename to package/kernel/mac80211/patches/ath9k/550-ath9k-disable-bands-via-dt.patch diff --git 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 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 7e3e1236f7..cd2bdbf1a0 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 @@ --- a/local-symbols +++ b/local-symbols -@@ -112,6 +112,7 @@ ATH9K_WOW= +@@ -113,6 +113,7 @@ ATH9K_WOW= ATH9K_RFKILL= ATH9K_CHANNEL_CONTEXT= ATH9K_PCOEM= @@ -381,7 +381,7 @@ ATH9K_HTC_DEBUGFS= --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig -@@ -60,6 +60,19 @@ config ATH9K_AHB +@@ -58,6 +58,19 @@ config ATH9K_AHB Say Y, if you have a SoC with a compatible built-in wireless MAC. Say N if unsure. diff --git a/package/kernel/mac80211/patches/ath/552-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch similarity index 99% rename from package/kernel/mac80211/patches/ath/552-ahb_of.patch rename to package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch index 2552bbc7a1..8fd6e4409b 100644 --- a/package/kernel/mac80211/patches/ath/552-ahb_of.patch +++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch @@ -325,7 +325,7 @@ #include "common.h" #include "debug.h" -@@ -1011,6 +1012,9 @@ struct ath_softc { +@@ -1012,6 +1013,9 @@ struct ath_softc { struct ath_hw *sc_ah; void __iomem *mem; int irq; diff --git a/package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch similarity index 100% rename from package/kernel/mac80211/patches/ath/553-ath9k_of_gpio_mask.patch rename to package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch index dc2295db1b..c9730e29fd 100644 --- a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -11,16 +11,6 @@ module loads successfully. Signed-off-by: Rafał Miłecki --- ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1557,6 +1557,7 @@ int __init brcmf_core_init(void) - { - if (!schedule_work(&brcmf_driver_work)) - return -EBUSY; -+ flush_work(&brcmf_driver_work); - - return 0; - } --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -431,6 +431,7 @@ struct brcmf_fw { diff --git a/package/kernel/mac80211/patches/build/001-fix_build.patch b/package/kernel/mac80211/patches/build/001-fix_build.patch index e57ca190e4..8f63d36e2e 100644 --- a/package/kernel/mac80211/patches/build/001-fix_build.patch +++ b/package/kernel/mac80211/patches/build/001-fix_build.patch @@ -55,8 +55,8 @@ - echo "" ;\ - done \ - ) > Kconfig.kernel ;\ -- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \ -- sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\ +- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ +- kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ - test "$$kver" != "" || echo "Kernel version parse failed!" ;\ - test "$$kver" != "" ;\ - kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ @@ -112,8 +112,8 @@ + @echo " done." + +Kconfig.versions: Kconfig.kernel -+ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \ -+ sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\ ++ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \ ++ kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\ + test "$$kver" != "" || echo "Kernel version parse failed!" ;\ + test "$$kver" != "" ;\ + kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ 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 cfa40e1bd2..d358cfe367 100644 --- 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 @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -5694,6 +5694,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") +@@ -5695,6 +5695,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") 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 f3130f7ae7..a35cf1875a 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 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -6279,6 +6279,8 @@ static int mwl8k_probe(struct pci_dev *p +@@ -6280,6 +6280,8 @@ static int mwl8k_probe(struct pci_dev *p priv->running_bsses = 0; @@ -9,7 +9,7 @@ return rc; err_stop_firmware: -@@ -6312,8 +6314,6 @@ static void mwl8k_remove(struct pci_dev +@@ -6313,8 +6315,6 @@ static void mwl8k_remove(struct pci_dev return; priv = hw->priv; 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..1c52132da6 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= +@@ -333,6 +333,7 @@ RT2X00_LIB_FIRMWARE= RT2X00_LIB_CRYPTO= RT2X00_LIB_LEDS= RT2X00_LIB_DEBUGFS= 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 new file mode 100644 index 0000000000..3daf65e967 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/002-v5.13-rtlwifi-implement-set_tim-by-update-beacon-content.patch @@ -0,0 +1,118 @@ +Date: Mon, 19 Apr 2021 14:59:56 +0800 +From: Ping-Ke Shih +To: +CC: , , + +Subject: [PATCH] rtlwifi: implement set_tim by update beacon content + +Once beacon content is changed, we update the content to wifi card by +send_beacon_frame(). Then, STA with PS can wake up properly to receive its +packets. + +Since we update beacon content to PCI wifi devices every beacon interval, +the only one usb device, 8192CU, needs to update beacon content when +mac80211 calling set_tim. + +Reported-by: Maciej S. Szmigiero +Signed-off-by: Ping-Ke Shih +Tested-by: Maciej S. Szmigiero +--- + drivers/net/wireless/realtek/rtlwifi/core.c | 32 +++++++++++++++++++++ + drivers/net/wireless/realtek/rtlwifi/core.h | 1 + + drivers/net/wireless/realtek/rtlwifi/usb.c | 3 ++ + drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 + + 4 files changed, 37 insertions(+) + +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -1018,6 +1018,25 @@ static void send_beacon_frame(struct iee + } + } + ++void rtl_update_beacon_work_callback(struct work_struct *work) ++{ ++ struct rtl_works *rtlworks = ++ container_of(work, struct rtl_works, update_beacon_work); ++ struct ieee80211_hw *hw = rtlworks->hw; ++ struct rtl_priv *rtlpriv = rtl_priv(hw); ++ struct ieee80211_vif *vif = rtlpriv->mac80211.vif; ++ ++ if (!vif) { ++ WARN_ONCE(true, "no vif to update beacon\n"); ++ return; ++ } ++ ++ mutex_lock(&rtlpriv->locks.conf_mutex); ++ send_beacon_frame(hw, vif); ++ mutex_unlock(&rtlpriv->locks.conf_mutex); ++} ++EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback); ++ + static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, +@@ -1747,6 +1766,18 @@ static void rtl_op_flush(struct ieee8021 + rtlpriv->intf_ops->flush(hw, queues, drop); + } + ++static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, ++ bool set) ++{ ++ struct rtl_priv *rtlpriv = rtl_priv(hw); ++ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); ++ ++ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) ++ schedule_work(&rtlpriv->works.update_beacon_work); ++ ++ return 0; ++} ++ + /* Description: + * This routine deals with the Power Configuration CMD + * parsing for RTL8723/RTL8188E Series IC. +@@ -1903,6 +1934,7 @@ const struct ieee80211_ops rtl_ops = { + .sta_add = rtl_op_sta_add, + .sta_remove = rtl_op_sta_remove, + .flush = rtl_op_flush, ++ .set_tim = rtl_op_set_tim, + }; + EXPORT_SYMBOL_GPL(rtl_ops); + +--- a/drivers/net/wireless/realtek/rtlwifi/core.h ++++ b/drivers/net/wireless/realtek/rtlwifi/core.h +@@ -60,5 +60,6 @@ void rtl_bb_delay(struct ieee80211_hw *h + bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); + bool rtl_btc_status_false(void); + void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval); ++void rtl_update_beacon_work_callback(struct work_struct *work); + + #endif +--- a/drivers/net/wireless/realtek/rtlwifi/usb.c ++++ b/drivers/net/wireless/realtek/rtlwifi/usb.c +@@ -807,6 +807,7 @@ static void rtl_usb_stop(struct ieee8021 + + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); ++ cancel_work_sync(&rtlpriv->works.update_beacon_work); + + flush_workqueue(rtlpriv->works.rtl_wq); + +@@ -1033,6 +1034,8 @@ int rtl_usb_probe(struct usb_interface * + rtl_fill_h2c_cmd_work_callback); + INIT_WORK(&rtlpriv->works.lps_change_work, + rtl_lps_change_work_callback); ++ INIT_WORK(&rtlpriv->works.update_beacon_work, ++ rtl_update_beacon_work_callback); + + rtlpriv->usb_data_index = 0; + init_completion(&rtlpriv->firmware_loading_complete); +--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h ++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h +@@ -2487,6 +2487,7 @@ struct rtl_works { + + struct work_struct lps_change_work; + struct work_struct fill_h2c_cmd; ++ struct work_struct update_beacon_work; + }; + + struct rtl_debug { diff --git a/package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch b/package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch new file mode 100644 index 0000000000..e1f66ac1c3 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/010-sync-nl80211_h.patch @@ -0,0 +1,297 @@ +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -655,6 +655,9 @@ + * When a security association was established on an 802.1X network using + * fast transition, this event should be followed by an + * %NL80211_CMD_PORT_AUTHORIZED event. ++ * Following a %NL80211_CMD_ROAM event userspace can issue ++ * %NL80211_CMD_GET_SCAN in order to obtain the scan information for the ++ * new BSS the card/driver roamed to. + * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify + * userspace that a connection was dropped by the AP or due to other + * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and +@@ -757,7 +760,8 @@ + * of any other interfaces, and other interfaces will again take + * precedence when they are used. + * +- * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. ++ * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface ++ * (no longer supported). + * + * @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform + * multicast to unicast conversion. When enabled, all multicast packets +@@ -1177,6 +1181,10 @@ + * includes the contents of the frame. %NL80211_ATTR_ACK flag is included + * if the recipient acknowledged the frame. + * ++ * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is ++ * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to ++ * specify the wiphy index to be applied to. ++ * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +@@ -1407,6 +1415,8 @@ enum nl80211_commands { + + NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, + ++ NL80211_CMD_SET_SAR_SPECS, ++ + /* add new commands above here */ + + /* used to define NL80211_CMD_MAX below */ +@@ -1750,8 +1760,9 @@ enum nl80211_commands { + * specify just a single bitrate, which is to be used for the beacon. + * The driver must also specify support for this with the extended + * features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY, +- * NL80211_EXT_FEATURE_BEACON_RATE_HT and +- * NL80211_EXT_FEATURE_BEACON_RATE_VHT. ++ * NL80211_EXT_FEATURE_BEACON_RATE_HT, ++ * NL80211_EXT_FEATURE_BEACON_RATE_VHT and ++ * NL80211_EXT_FEATURE_BEACON_RATE_HE. + * + * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain + * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. +@@ -1955,8 +1966,15 @@ enum nl80211_commands { + * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire + * probe-response frame. The DA field in the 802.11 header is zero-ed out, + * to be filled by the FW. +- * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable +- * this feature. Currently, only supported in mac80211 drivers. ++ * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable ++ * this feature during association. This is a flag attribute. ++ * Currently only supported in mac80211 drivers. ++ * @NL80211_ATTR_DISABLE_VHT: Force VHT capable interfaces to disable ++ * this feature during association. This is a flag attribute. ++ * Currently only supported in mac80211 drivers. ++ * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable ++ * this feature during association. This is a flag attribute. ++ * Currently only supported in mac80211 drivers. + * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the + * ATTR_HT_CAPABILITY to which attention should be paid. + * Currently, only mac80211 NICs support this feature. +@@ -2077,7 +2095,8 @@ enum nl80211_commands { + * until the channel switch event. + * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission + * must be blocked on the current channel (before the channel switch +- * operation). ++ * operation). Also included in the channel switch started event if quiet ++ * was requested by the AP. + * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information + * for the time while performing a channel switch. + * @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel +@@ -2527,6 +2546,20 @@ enum nl80211_commands { + * override mask. Used with NL80211_ATTR_S1G_CAPABILITY in + * NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT. + * ++ * @NL80211_ATTR_SAE_PWE: Indicates the mechanism(s) allowed for SAE PWE ++ * derivation in WPA3-Personal networks which are using SAE authentication. ++ * This is a u8 attribute that encapsulates one of the values from ++ * &enum nl80211_sae_pwe_mechanism. ++ * ++ * @NL80211_ATTR_SAR_SPEC: SAR power limitation specification when ++ * used with %NL80211_CMD_SET_SAR_SPECS. The message contains fields ++ * of %nl80211_sar_attrs which specifies the sar type and related ++ * sar specs. Sar specs contains array of %nl80211_sar_specs_attrs. ++ * ++ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and ++ * disassoc events to indicate that an immediate reconnect to the AP ++ * is desired. ++ * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -3016,6 +3049,14 @@ enum nl80211_attrs { + NL80211_ATTR_S1G_CAPABILITY, + NL80211_ATTR_S1G_CAPABILITY_MASK, + ++ NL80211_ATTR_SAE_PWE, ++ ++ NL80211_ATTR_RECONNECT_REQUESTED, ++ ++ NL80211_ATTR_SAR_SPEC, ++ ++ NL80211_ATTR_DISABLE_HE, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +@@ -5896,6 +5937,19 @@ enum nl80211_feature_flags { + * @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports + * unsolicited broadcast probe response transmission + * ++ * @NL80211_EXT_FEATURE_BEACON_RATE_HE: Driver supports beacon rate ++ * configuration (AP/mesh) with HE rates. ++ * ++ * @NL80211_EXT_FEATURE_SECURE_LTF: Device supports secure LTF measurement ++ * exchange protocol. ++ * ++ * @NL80211_EXT_FEATURE_SECURE_RTT: Device supports secure RTT measurement ++ * exchange protocol. ++ * ++ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management ++ * frame protection for all management frames exchanged during the ++ * negotiation and range measurement procedure. ++ * + * @NUM_NL80211_EXT_FEATURES: number of extended features. + * @MAX_NL80211_EXT_FEATURES: highest extended feature index. + */ +@@ -5956,6 +6010,10 @@ enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_SAE_OFFLOAD_AP, + NL80211_EXT_FEATURE_FILS_DISCOVERY, + NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP, ++ NL80211_EXT_FEATURE_BEACON_RATE_HE, ++ NL80211_EXT_FEATURE_SECURE_LTF, ++ NL80211_EXT_FEATURE_SECURE_RTT, ++ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, +@@ -6253,11 +6311,13 @@ struct nl80211_vendor_cmd_info { + * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable. + * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable. + * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable. ++ * @NL80211_TDLS_PEER_HE: TDLS peer is HE capable. + */ + enum nl80211_tdls_peer_capability { + NL80211_TDLS_PEER_HT = 1<<0, + NL80211_TDLS_PEER_VHT = 1<<1, + NL80211_TDLS_PEER_WMM = 1<<2, ++ NL80211_TDLS_PEER_HE = 1<<3, + }; + + /** +@@ -6849,6 +6909,9 @@ enum nl80211_peer_measurement_ftm_capa { + * if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor + * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based + * ranging will be used. ++ * @NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK: negotiate for LMR feedback. Only ++ * valid if either %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED or ++ * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set. + * + * @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal + * @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number +@@ -6867,6 +6930,7 @@ enum nl80211_peer_measurement_ftm_req { + NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC, + NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED, + NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED, ++ NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK, + + /* keep last */ + NUM_NL80211_PMSR_FTM_REQ_ATTR, +@@ -7124,4 +7188,115 @@ enum nl80211_unsol_bcast_probe_resp_attr + NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX = + __NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1 + }; ++ ++/** ++ * enum nl80211_sae_pwe_mechanism - The mechanism(s) allowed for SAE PWE ++ * derivation. Applicable only when WPA3-Personal SAE authentication is ++ * used. ++ * ++ * @NL80211_SAE_PWE_UNSPECIFIED: not specified, used internally to indicate that ++ * attribute is not present from userspace. ++ * @NL80211_SAE_PWE_HUNT_AND_PECK: hunting-and-pecking loop only ++ * @NL80211_SAE_PWE_HASH_TO_ELEMENT: hash-to-element only ++ * @NL80211_SAE_PWE_BOTH: both hunting-and-pecking loop and hash-to-element ++ * can be used. ++ */ ++enum nl80211_sae_pwe_mechanism { ++ NL80211_SAE_PWE_UNSPECIFIED, ++ NL80211_SAE_PWE_HUNT_AND_PECK, ++ NL80211_SAE_PWE_HASH_TO_ELEMENT, ++ NL80211_SAE_PWE_BOTH, ++}; ++ ++/** ++ * enum nl80211_sar_type - type of SAR specs ++ * ++ * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit ++ * ++ */ ++enum nl80211_sar_type { ++ NL80211_SAR_TYPE_POWER, ++ ++ /* add new type here */ ++ ++ /* Keep last */ ++ NUM_NL80211_SAR_TYPE, ++}; ++ ++/** ++ * enum nl80211_sar_attrs - Attributes for SAR spec ++ * ++ * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type. ++ * ++ * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power ++ * limit specifications. Each specification contains a set ++ * of %nl80211_sar_specs_attrs. ++ * ++ * For SET operation, it contains array of %NL80211_SAR_ATTR_SPECS_POWER ++ * and %NL80211_SAR_ATTR_SPECS_RANGE_INDEX. ++ * ++ * For sar_capa dump, it contains array of ++ * %NL80211_SAR_ATTR_SPECS_START_FREQ ++ * and %NL80211_SAR_ATTR_SPECS_END_FREQ. ++ * ++ * @__NL80211_SAR_ATTR_LAST: Internal ++ * @NL80211_SAR_ATTR_MAX: highest sar attribute ++ * ++ * These attributes are used with %NL80211_CMD_SET_SAR_SPEC ++ */ ++enum nl80211_sar_attrs { ++ __NL80211_SAR_ATTR_INVALID, ++ ++ NL80211_SAR_ATTR_TYPE, ++ NL80211_SAR_ATTR_SPECS, ++ ++ __NL80211_SAR_ATTR_LAST, ++ NL80211_SAR_ATTR_MAX = __NL80211_SAR_ATTR_LAST - 1, ++}; ++ ++/** ++ * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs ++ * ++ * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual ++ * power limit value in units of 0.25 dBm if type is ++ * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm). ++ * 0 means userspace doesn't have SAR limitation on this associated range. ++ * ++ * @NL80211_SAR_ATTR_SPECS_RANGE_INDEX: Required (u32) value to specify the ++ * index of exported freq range table and the associated power limitation ++ * is applied to this range. ++ * ++ * Userspace isn't required to set all the ranges advertised by WLAN driver, ++ * and userspace can skip some certain ranges. These skipped ranges don't ++ * have SAR limitations, and they are same as setting the ++ * %NL80211_SAR_ATTR_SPECS_POWER to any unreasonable high value because any ++ * value higher than regulatory allowed value just means SAR power ++ * limitation is removed, but it's required to set at least one range. ++ * It's not allowed to set duplicated range in one SET operation. ++ * ++ * Every SET operation overwrites previous SET operation. ++ * ++ * @NL80211_SAR_ATTR_SPECS_START_FREQ: Required (u32) value to specify the start ++ * frequency of this range edge when registering SAR capability to wiphy. ++ * It's not a channel center frequency. The unit is kHz. ++ * ++ * @NL80211_SAR_ATTR_SPECS_END_FREQ: Required (u32) value to specify the end ++ * frequency of this range edge when registering SAR capability to wiphy. ++ * It's not a channel center frequency. The unit is kHz. ++ * ++ * @__NL80211_SAR_ATTR_SPECS_LAST: Internal ++ * @NL80211_SAR_ATTR_SPECS_MAX: highest sar specs attribute ++ */ ++enum nl80211_sar_specs_attrs { ++ __NL80211_SAR_ATTR_SPECS_INVALID, ++ ++ NL80211_SAR_ATTR_SPECS_POWER, ++ NL80211_SAR_ATTR_SPECS_RANGE_INDEX, ++ NL80211_SAR_ATTR_SPECS_START_FREQ, ++ NL80211_SAR_ATTR_SPECS_END_FREQ, ++ ++ __NL80211_SAR_ATTR_SPECS_LAST, ++ NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1, ++}; ++ + #endif /* __LINUX_NL80211_H */ diff --git a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch deleted file mode 100644 index 7b036e4e4c..0000000000 --- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch +++ /dev/null @@ -1,698 +0,0 @@ ---- a/net/mac80211/Makefile -+++ b/net/mac80211/Makefile -@@ -7,7 +7,6 @@ mac80211-y := \ - driver-ops.o \ - sta_info.o \ - wep.o \ -- aead_api.o \ - wpa.o \ - scan.o offchannel.o \ - ht.o agg-tx.o agg-rx.o \ -@@ -19,8 +18,8 @@ mac80211-y := \ - rate.o \ - michael.o \ - tkip.o \ -+ aes_ccm.o \ - aes_cmac.o \ -- aes_gmac.o \ - fils_aead.o \ - cfg.o \ - ethtool.o \ ---- a/net/mac80211/aead_api.c -+++ /dev/null -@@ -1,112 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* -- * Copyright 2003-2004, Instant802 Networks, Inc. -- * Copyright 2005-2006, Devicescape Software, Inc. -- * Copyright 2014-2015, Qualcomm Atheros, Inc. -- * -- * Rewrite: Copyright (C) 2013 Linaro Ltd -- */ -- --#include --#include --#include --#include --#include -- --#include "aead_api.h" -- --int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, -- u8 *data, size_t data_len, u8 *mic) --{ -- size_t mic_len = crypto_aead_authsize(tfm); -- struct scatterlist sg[3]; -- struct aead_request *aead_req; -- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); -- u8 *__aad; -- -- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); -- if (!aead_req) -- return -ENOMEM; -- -- __aad = (u8 *)aead_req + reqsize; -- memcpy(__aad, aad, aad_len); -- -- sg_init_table(sg, 3); -- sg_set_buf(&sg[0], __aad, aad_len); -- sg_set_buf(&sg[1], data, data_len); -- sg_set_buf(&sg[2], mic, mic_len); -- -- aead_request_set_tfm(aead_req, tfm); -- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); -- aead_request_set_ad(aead_req, sg[0].length); -- -- crypto_aead_encrypt(aead_req); -- kfree_sensitive(aead_req); -- -- return 0; --} -- --int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, -- u8 *data, size_t data_len, u8 *mic) --{ -- size_t mic_len = crypto_aead_authsize(tfm); -- struct scatterlist sg[3]; -- struct aead_request *aead_req; -- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); -- u8 *__aad; -- int err; -- -- if (data_len == 0) -- return -EINVAL; -- -- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); -- if (!aead_req) -- return -ENOMEM; -- -- __aad = (u8 *)aead_req + reqsize; -- memcpy(__aad, aad, aad_len); -- -- sg_init_table(sg, 3); -- sg_set_buf(&sg[0], __aad, aad_len); -- sg_set_buf(&sg[1], data, data_len); -- sg_set_buf(&sg[2], mic, mic_len); -- -- aead_request_set_tfm(aead_req, tfm); -- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); -- aead_request_set_ad(aead_req, sg[0].length); -- -- err = crypto_aead_decrypt(aead_req); -- kfree_sensitive(aead_req); -- -- return err; --} -- --struct crypto_aead * --aead_key_setup_encrypt(const char *alg, const u8 key[], -- size_t key_len, size_t mic_len) --{ -- struct crypto_aead *tfm; -- int err; -- -- tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC); -- if (IS_ERR(tfm)) -- return tfm; -- -- err = crypto_aead_setkey(tfm, key, key_len); -- if (err) -- goto free_aead; -- err = crypto_aead_setauthsize(tfm, mic_len); -- if (err) -- goto free_aead; -- -- return tfm; -- --free_aead: -- crypto_free_aead(tfm); -- return ERR_PTR(err); --} -- --void aead_key_free(struct crypto_aead *tfm) --{ -- crypto_free_aead(tfm); --} ---- a/net/mac80211/aead_api.h -+++ /dev/null -@@ -1,23 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ -- --#ifndef _AEAD_API_H --#define _AEAD_API_H -- --#include --#include -- --struct crypto_aead * --aead_key_setup_encrypt(const char *alg, const u8 key[], -- size_t key_len, size_t mic_len); -- --int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, -- size_t aad_len, u8 *data, -- size_t data_len, u8 *mic); -- --int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, -- size_t aad_len, u8 *data, -- size_t data_len, u8 *mic); -- --void aead_key_free(struct crypto_aead *tfm); -- --#endif /* _AEAD_API_H */ ---- a/net/mac80211/aes_ccm.h -+++ b/net/mac80211/aes_ccm.h -@@ -7,39 +7,17 @@ - #ifndef AES_CCM_H - #define AES_CCM_H - --#include "aead_api.h" -+#include - --#define CCM_AAD_LEN 32 -- --static inline struct crypto_aead * --ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len) --{ -- return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len); --} -- --static inline int --ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, -- u8 *b_0, u8 *aad, u8 *data, -- size_t data_len, u8 *mic) --{ -- return aead_encrypt(tfm, b_0, aad + 2, -- be16_to_cpup((__be16 *)aad), -- data, data_len, mic); --} -- --static inline int --ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, -- u8 *b_0, u8 *aad, u8 *data, -- size_t data_len, u8 *mic) --{ -- return aead_decrypt(tfm, b_0, aad + 2, -- be16_to_cpup((__be16 *)aad), -- data, data_len, mic); --} -- --static inline void ieee80211_aes_key_free(struct crypto_aead *tfm) --{ -- return aead_key_free(tfm); --} -+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], -+ size_t key_len, -+ size_t mic_len); -+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic, -+ size_t mic_len); -+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic, -+ size_t mic_len); -+void ieee80211_aes_key_free(struct crypto_cipher *tfm); - - #endif /* AES_CCM_H */ ---- /dev/null -+++ b/net/mac80211/aes_gcm.c -@@ -0,0 +1,109 @@ -+/* -+ * Copyright 2014-2015, Qualcomm Atheros, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include "key.h" -+#include "aes_gcm.h" -+ -+int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic) -+{ -+ struct scatterlist sg[3]; -+ struct aead_request *aead_req; -+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); -+ u8 *__aad; -+ -+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); -+ if (!aead_req) -+ return -ENOMEM; -+ -+ __aad = (u8 *)aead_req + reqsize; -+ memcpy(__aad, aad, GCM_AAD_LEN); -+ -+ sg_init_table(sg, 3); -+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); -+ sg_set_buf(&sg[1], data, data_len); -+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); -+ -+ aead_request_set_tfm(aead_req, tfm); -+ aead_request_set_crypt(aead_req, sg, sg, data_len, j_0); -+ aead_request_set_ad(aead_req, sg[0].length); -+ -+ crypto_aead_encrypt(aead_req); -+ kzfree(aead_req); -+ return 0; -+} -+ -+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic) -+{ -+ struct scatterlist sg[3]; -+ struct aead_request *aead_req; -+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); -+ u8 *__aad; -+ int err; -+ -+ if (data_len == 0) -+ return -EINVAL; -+ -+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); -+ if (!aead_req) -+ return -ENOMEM; -+ -+ __aad = (u8 *)aead_req + reqsize; -+ memcpy(__aad, aad, GCM_AAD_LEN); -+ -+ sg_init_table(sg, 3); -+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); -+ sg_set_buf(&sg[1], data, data_len); -+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); -+ -+ aead_request_set_tfm(aead_req, tfm); -+ aead_request_set_crypt(aead_req, sg, sg, -+ data_len + IEEE80211_GCMP_MIC_LEN, j_0); -+ aead_request_set_ad(aead_req, sg[0].length); -+ -+ err = crypto_aead_decrypt(aead_req); -+ kzfree(aead_req); -+ -+ return err; -+} -+ -+struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], -+ size_t key_len) -+{ -+ struct crypto_aead *tfm; -+ int err; -+ -+ tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); -+ if (IS_ERR(tfm)) -+ return tfm; -+ -+ err = crypto_aead_setkey(tfm, key, key_len); -+ if (err) -+ goto free_aead; -+ err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); -+ if (err) -+ goto free_aead; -+ -+ return tfm; -+ -+free_aead: -+ crypto_free_aead(tfm); -+ return ERR_PTR(err); -+} -+ -+void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) -+{ -+ crypto_free_aead(tfm); -+} ---- a/net/mac80211/aes_gcm.h -+++ b/net/mac80211/aes_gcm.h -@@ -6,38 +6,30 @@ - #ifndef AES_GCM_H - #define AES_GCM_H - --#include "aead_api.h" -+#include - --#define GCM_AAD_LEN 32 -- --static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, -- u8 *j_0, u8 *aad, u8 *data, -- size_t data_len, u8 *mic) -+static inline void -+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic) - { -- return aead_encrypt(tfm, j_0, aad + 2, -- be16_to_cpup((__be16 *)aad), -- data, data_len, mic); - } - --static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, -- u8 *j_0, u8 *aad, u8 *data, -- size_t data_len, u8 *mic) -+static inline int -+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic) - { -- return aead_decrypt(tfm, j_0, aad + 2, -- be16_to_cpup((__be16 *)aad), -- data, data_len, mic); -+ return -EOPNOTSUPP; - } - - static inline struct crypto_aead * - ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) - { -- return aead_key_setup_encrypt("gcm(aes)", key, -- key_len, IEEE80211_GCMP_MIC_LEN); -+ return NULL; - } - --static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) -+static inline void -+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) - { -- return aead_key_free(tfm); - } - - #endif /* AES_GCM_H */ ---- a/net/mac80211/wpa.c -+++ b/net/mac80211/wpa.c -@@ -311,7 +311,8 @@ ieee80211_crypto_tkip_decrypt(struct iee - } - - --static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) -+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, -+ u16 data_len) - { - __le16 mask_fc; - int a4_included, mgmt; -@@ -341,14 +342,8 @@ static void ccmp_special_blocks(struct s - else - qos_tid = 0; - -- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC -- * mode authentication are not allowed to collide, yet both are derived -- * from this vector b_0. We only set L := 1 here to indicate that the -- * data size can be represented in (L+1) bytes. The CCM layer will take -- * care of storing the data length in the top (L+1) bytes and setting -- * and clearing the other bits as is required to derive the two IVs. -- */ -- b_0[0] = 0x1; -+ /* First block, b_0 */ -+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ - - /* Nonce: Nonce Flags | A2 | PN - * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) -@@ -356,6 +351,8 @@ static void ccmp_special_blocks(struct s - b_0[1] = qos_tid | (mgmt << 4); - memcpy(&b_0[2], hdr->addr2, ETH_ALEN); - memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); -+ /* l(m) */ -+ put_unaligned_be16(data_len, &b_0[14]); - - /* AAD (extra authenticate-only data) / masked 802.11 header - * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ -@@ -412,7 +409,7 @@ static int ccmp_encrypt_skb(struct ieee8 - u8 *pos; - u8 pn[6]; - u64 pn64; -- u8 aad[CCM_AAD_LEN]; -+ u8 aad[2 * AES_BLOCK_SIZE]; - u8 b_0[AES_BLOCK_SIZE]; - - if (info->control.hw_key && -@@ -467,9 +464,11 @@ static int ccmp_encrypt_skb(struct ieee8 - return 0; - - pos += IEEE80211_CCMP_HDR_LEN; -- ccmp_special_blocks(skb, pn, b_0, aad); -- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, -- skb_put(skb, mic_len)); -+ ccmp_special_blocks(skb, pn, b_0, aad, len); -+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, -+ skb_put(skb, mic_len), mic_len); -+ -+ return 0; - } - - -@@ -542,13 +541,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee - u8 aad[2 * AES_BLOCK_SIZE]; - u8 b_0[AES_BLOCK_SIZE]; - /* hardware didn't decrypt/verify MIC */ -- ccmp_special_blocks(skb, pn, b_0, aad); -+ ccmp_special_blocks(skb, pn, b_0, aad, data_len); - - if (ieee80211_aes_ccm_decrypt( - key->u.ccmp.tfm, b_0, aad, - skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, - data_len, -- skb->data + skb->len - mic_len)) -+ skb->data + skb->len - mic_len, mic_len)) - return RX_DROP_UNUSABLE; - } - -@@ -643,7 +642,7 @@ static int gcmp_encrypt_skb(struct ieee8 - u8 *pos; - u8 pn[6]; - u64 pn64; -- u8 aad[GCM_AAD_LEN]; -+ u8 aad[2 * AES_BLOCK_SIZE]; - u8 j_0[AES_BLOCK_SIZE]; - - if (info->control.hw_key && -@@ -700,8 +699,10 @@ static int gcmp_encrypt_skb(struct ieee8 - - pos += IEEE80211_GCMP_HDR_LEN; - gcmp_special_blocks(skb, pn, j_0, aad); -- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, -- skb_put(skb, IEEE80211_GCMP_MIC_LEN)); -+ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, -+ skb_put(skb, IEEE80211_GCMP_MIC_LEN)); -+ -+ return 0; - } - - ieee80211_tx_result -@@ -1128,9 +1129,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct - struct ieee80211_key *key = tx->key; - struct ieee80211_mmie_16 *mmie; - struct ieee80211_hdr *hdr; -- u8 aad[GMAC_AAD_LEN]; -+ u8 aad[20]; - u64 pn64; -- u8 nonce[GMAC_NONCE_LEN]; -+ u8 nonce[12]; - - if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) - return TX_DROP; -@@ -1176,7 +1177,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct ieee80211_key *key = rx->key; - struct ieee80211_mmie_16 *mmie; -- u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN]; -+ u8 aad[20], *mic, ipn[6], nonce[12]; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - - if (!ieee80211_is_mgmt(hdr->frame_control)) ---- /dev/null -+++ b/net/mac80211/aes_ccm.c -@@ -0,0 +1,144 @@ -+/* -+ * Copyright 2003-2004, Instant802 Networks, Inc. -+ * Copyright 2005-2006, Devicescape Software, Inc. -+ * -+ * Rewrite: Copyright (C) 2013 Linaro Ltd -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "key.h" -+#include "aes_ccm.h" -+ -+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0, -+ u8 *a, u8 *b) -+{ -+ int i; -+ -+ crypto_cipher_encrypt_one(tfm, b, b_0); -+ -+ /* Extra Authenticate-only data (always two AES blocks) */ -+ for (i = 0; i < AES_BLOCK_SIZE; i++) -+ aad[i] ^= b[i]; -+ crypto_cipher_encrypt_one(tfm, b, aad); -+ -+ aad += AES_BLOCK_SIZE; -+ -+ for (i = 0; i < AES_BLOCK_SIZE; i++) -+ aad[i] ^= b[i]; -+ crypto_cipher_encrypt_one(tfm, a, aad); -+ -+ /* Mask out bits from auth-only-b_0 */ -+ b_0[0] &= 0x07; -+ -+ /* S_0 is used to encrypt T (= MIC) */ -+ b_0[14] = 0; -+ b_0[15] = 0; -+ crypto_cipher_encrypt_one(tfm, s_0, b_0); -+} -+ -+ -+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic, -+ size_t mic_len) -+{ -+ int i, j, last_len, num_blocks; -+ u8 b[AES_BLOCK_SIZE]; -+ u8 s_0[AES_BLOCK_SIZE]; -+ u8 e[AES_BLOCK_SIZE]; -+ u8 *pos, *cpos; -+ -+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); -+ last_len = data_len % AES_BLOCK_SIZE; -+ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b); -+ -+ /* Process payload blocks */ -+ pos = data; -+ cpos = data; -+ for (j = 1; j <= num_blocks; j++) { -+ int blen = (j == num_blocks && last_len) ? -+ last_len : AES_BLOCK_SIZE; -+ -+ /* Authentication followed by encryption */ -+ for (i = 0; i < blen; i++) -+ b[i] ^= pos[i]; -+ crypto_cipher_encrypt_one(tfm, b, b); -+ -+ b_0[14] = (j >> 8) & 0xff; -+ b_0[15] = j & 0xff; -+ crypto_cipher_encrypt_one(tfm, e, b_0); -+ for (i = 0; i < blen; i++) -+ *cpos++ = *pos++ ^ e[i]; -+ } -+ -+ for (i = 0; i < mic_len; i++) -+ mic[i] = b[i] ^ s_0[i]; -+} -+ -+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, -+ u8 *data, size_t data_len, u8 *mic, -+ size_t mic_len) -+{ -+ int i, j, last_len, num_blocks; -+ u8 *pos, *cpos; -+ u8 a[AES_BLOCK_SIZE]; -+ u8 b[AES_BLOCK_SIZE]; -+ u8 s_0[AES_BLOCK_SIZE]; -+ -+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); -+ last_len = data_len % AES_BLOCK_SIZE; -+ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b); -+ -+ /* Process payload blocks */ -+ cpos = data; -+ pos = data; -+ for (j = 1; j <= num_blocks; j++) { -+ int blen = (j == num_blocks && last_len) ? -+ last_len : AES_BLOCK_SIZE; -+ -+ /* Decryption followed by authentication */ -+ b_0[14] = (j >> 8) & 0xff; -+ b_0[15] = j & 0xff; -+ crypto_cipher_encrypt_one(tfm, b, b_0); -+ for (i = 0; i < blen; i++) { -+ *pos = *cpos++ ^ b[i]; -+ a[i] ^= *pos++; -+ } -+ crypto_cipher_encrypt_one(tfm, a, a); -+ } -+ -+ for (i = 0; i < mic_len; i++) { -+ if ((mic[i] ^ s_0[i]) != a[i]) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], -+ size_t key_len, -+ size_t mic_len) -+{ -+ struct crypto_cipher *tfm; -+ -+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); -+ if (!IS_ERR(tfm)) -+ crypto_cipher_setkey(tfm, key, key_len); -+ -+ return tfm; -+} -+ -+ -+void ieee80211_aes_key_free(struct crypto_cipher *tfm) -+{ -+ crypto_free_cipher(tfm); -+} ---- a/net/mac80211/Kconfig -+++ b/net/mac80211/Kconfig -@@ -6,8 +6,6 @@ config MAC80211 - depends on CRYPTO - select BPAUTO_CRYPTO_LIB_ARC4 - depends on CRYPTO_AES -- depends on CRYPTO_CCM -- depends on CRYPTO_GCM - depends on CRYPTO_CMAC - depends on CRC32 - help ---- a/net/mac80211/aes_gmac.h -+++ b/net/mac80211/aes_gmac.h -@@ -12,10 +12,22 @@ - #define GMAC_MIC_LEN 16 - #define GMAC_NONCE_LEN 12 - --struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], -- size_t key_len); --int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, -- const u8 *data, size_t data_len, u8 *mic); --void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm); -+static inline struct crypto_aead * -+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len) -+{ -+ return NULL; -+} -+ -+static inline int -+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, -+ const u8 *data, size_t data_len, u8 *mic) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void -+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm) -+{ -+} - - #endif /* AES_GMAC_H */ ---- a/net/mac80211/key.h -+++ b/net/mac80211/key.h -@@ -89,7 +89,7 @@ struct ieee80211_key { - * Management frames. - */ - u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; -- struct crypto_aead *tfm; -+ struct crypto_cipher *tfm; - u32 replays; /* dot11RSNAStatsCCMPReplays */ - } ccmp; - struct { diff --git a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch deleted file mode 100644 index 9c6e971f9d..0000000000 --- a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch +++ /dev/null @@ -1,32 +0,0 @@ -Disable FILS support, since it pulls in crypto hash support - ---- a/net/mac80211/fils_aead.h -+++ b/net/mac80211/fils_aead.h -@@ -7,7 +7,7 @@ - #ifndef FILS_AEAD_H - #define FILS_AEAD_H - --#if LINUX_VERSION_IS_GEQ(4,3,0) -+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ - int fils_encrypt_assoc_req(struct sk_buff *skb, - struct ieee80211_mgd_assoc_data *assoc_data); - int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata, ---- a/net/mac80211/fils_aead.c -+++ b/net/mac80211/fils_aead.c -@@ -1,4 +1,4 @@ --#if LINUX_VERSION_IS_GEQ(4,3,0) -+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ - // SPDX-License-Identifier: GPL-2.0-only - /* - * FILS AEAD for (Re)Association Request/Response frames ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -591,7 +591,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ - NL80211_FEATURE_MAC_ON_CREATE | - NL80211_FEATURE_USERSPACE_MPM | - NL80211_FEATURE_FULL_AP_CLIENT_STATE; --#if LINUX_VERSION_IS_GEQ(4,3,0) -+#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); - #endif - wiphy_ext_feature_set(wiphy, diff --git a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch deleted file mode 100644 index c3bf7ccc7a..0000000000 --- a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch +++ /dev/null @@ -1,230 +0,0 @@ -From: Felix Fietkau -Date: Sat, 7 Oct 2017 09:37:28 +0200 -Subject: [PATCH] Revert "mac80211: aes-cmac: switch to shash CMAC - driver" - -This reverts commit 26717828b75dd5c46e97f7f4a9b937d038bb2852. -Reduces mac80211 dependencies for LEDE - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/aes_cmac.c -+++ b/net/mac80211/aes_cmac.c -@@ -19,67 +19,151 @@ - #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ - #define AAD_LEN 20 - --static const u8 zero[CMAC_TLEN_256]; - --void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, -+void gf_mulx(u8 *pad) -+{ -+ int i, carry; -+ -+ carry = pad[0] & 0x80; -+ for (i = 0; i < AES_BLOCK_SIZE - 1; i++) -+ pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); -+ pad[AES_BLOCK_SIZE - 1] <<= 1; -+ if (carry) -+ pad[AES_BLOCK_SIZE - 1] ^= 0x87; -+} -+ -+void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, -+ const u8 *addr[], const size_t *len, u8 *mac, -+ size_t mac_len) -+{ -+ u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; -+ const u8 *pos, *end; -+ size_t i, e, left, total_len; -+ -+ memset(cbc, 0, AES_BLOCK_SIZE); -+ -+ total_len = 0; -+ for (e = 0; e < num_elem; e++) -+ total_len += len[e]; -+ left = total_len; -+ -+ e = 0; -+ pos = addr[0]; -+ end = pos + len[0]; -+ -+ while (left >= AES_BLOCK_SIZE) { -+ for (i = 0; i < AES_BLOCK_SIZE; i++) { -+ cbc[i] ^= *pos++; -+ if (pos >= end) { -+ e++; -+ pos = addr[e]; -+ end = pos + len[e]; -+ } -+ } -+ if (left > AES_BLOCK_SIZE) -+ crypto_cipher_encrypt_one(tfm, cbc, cbc); -+ left -= AES_BLOCK_SIZE; -+ } -+ -+ memset(pad, 0, AES_BLOCK_SIZE); -+ crypto_cipher_encrypt_one(tfm, pad, pad); -+ gf_mulx(pad); -+ -+ if (left || total_len == 0) { -+ for (i = 0; i < left; i++) { -+ cbc[i] ^= *pos++; -+ if (pos >= end) { -+ e++; -+ pos = addr[e]; -+ end = pos + len[e]; -+ } -+ } -+ cbc[left] ^= 0x80; -+ gf_mulx(pad); -+ } -+ -+ for (i = 0; i < AES_BLOCK_SIZE; i++) -+ pad[i] ^= cbc[i]; -+ crypto_cipher_encrypt_one(tfm, pad, pad); -+ memcpy(mac, pad, mac_len); -+} -+ -+ -+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic) - { -- SHASH_DESC_ON_STACK(desc, tfm); -- u8 out[AES_BLOCK_SIZE]; -+ const u8 *addr[4]; -+ size_t len[4]; -+ u8 zero[CMAC_TLEN]; - const __le16 *fc; - -- desc->tfm = tfm; -- -- crypto_shash_init(desc); -- crypto_shash_update(desc, aad, AAD_LEN); -+ memset(zero, 0, CMAC_TLEN); -+ addr[0] = aad; -+ len[0] = AAD_LEN; - fc = (const __le16 *)aad; - if (ieee80211_is_beacon(*fc)) { - /* mask Timestamp field to zero */ -- crypto_shash_update(desc, zero, 8); -- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); -+ addr[1] = zero; -+ len[1] = 8; -+ addr[2] = data + 8; -+ len[2] = data_len - 8 - CMAC_TLEN; -+ addr[3] = zero; -+ len[3] = CMAC_TLEN; -+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN); - } else { -- crypto_shash_update(desc, data, data_len - CMAC_TLEN); -+ addr[1] = data; -+ len[1] = data_len - CMAC_TLEN; -+ addr[2] = zero; -+ len[2] = CMAC_TLEN; -+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); - } -- crypto_shash_finup(desc, zero, CMAC_TLEN, out); -- -- memcpy(mic, out, CMAC_TLEN); - } - --void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, -+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic) - { -- SHASH_DESC_ON_STACK(desc, tfm); -+ const u8 *addr[4]; -+ size_t len[4]; -+ u8 zero[CMAC_TLEN_256]; - const __le16 *fc; - -- desc->tfm = tfm; -- -- crypto_shash_init(desc); -- crypto_shash_update(desc, aad, AAD_LEN); -+ memset(zero, 0, CMAC_TLEN_256); -+ addr[0] = aad; -+ len[0] = AAD_LEN; -+ addr[1] = data; - fc = (const __le16 *)aad; - if (ieee80211_is_beacon(*fc)) { - /* mask Timestamp field to zero */ -- crypto_shash_update(desc, zero, 8); -- crypto_shash_update(desc, data + 8, -- data_len - 8 - CMAC_TLEN_256); -+ addr[1] = zero; -+ len[1] = 8; -+ addr[2] = data + 8; -+ len[2] = data_len - 8 - CMAC_TLEN_256; -+ addr[3] = zero; -+ len[3] = CMAC_TLEN_256; -+ aes_cmac_vector(tfm, 4, addr, len, mic, CMAC_TLEN_256); - } else { -- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); -+ addr[1] = data; -+ len[1] = data_len - CMAC_TLEN_256; -+ addr[2] = zero; -+ len[2] = CMAC_TLEN_256; -+ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); - } -- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); - } - --struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], -- size_t key_len) -+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], -+ size_t key_len) - { -- struct crypto_shash *tfm; -+ struct crypto_cipher *tfm; - -- tfm = crypto_alloc_shash("cmac(aes)", 0, 0); -+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (!IS_ERR(tfm)) -- crypto_shash_setkey(tfm, key, key_len); -+ crypto_cipher_setkey(tfm, key, key_len); - - return tfm; - } - --void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm) -+ -+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) - { -- crypto_free_shash(tfm); -+ crypto_free_cipher(tfm); - } ---- a/net/mac80211/aes_cmac.h -+++ b/net/mac80211/aes_cmac.h -@@ -7,14 +7,13 @@ - #define AES_CMAC_H - - #include --#include - --struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], -- size_t key_len); --void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, -+struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], -+ size_t key_len); -+void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic); --void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, -+void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, - const u8 *data, size_t data_len, u8 *mic); --void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); -+void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); - - #endif /* AES_CMAC_H */ ---- a/net/mac80211/key.h -+++ b/net/mac80211/key.h -@@ -94,7 +94,7 @@ struct ieee80211_key { - } ccmp; - struct { - u8 rx_pn[IEEE80211_CMAC_PN_LEN]; -- struct crypto_shash *tfm; -+ struct crypto_cipher *tfm; - u32 replays; /* dot11RSNAStatsCMACReplays */ - u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ - } aes_cmac; diff --git a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch deleted file mode 100644 index df67d2f101..0000000000 --- a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/mac80211/Kconfig -+++ b/net/mac80211/Kconfig -@@ -6,7 +6,6 @@ config MAC80211 - depends on CRYPTO - select BPAUTO_CRYPTO_LIB_ARC4 - depends on CRYPTO_AES -- depends on CRYPTO_CMAC - depends on CRC32 - help - This option enables the hardware independent IEEE 802.11 diff --git a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch index 8a717558a7..8d086625e4 100644 --- a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch +++ b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch @@ -18,7 +18,7 @@ static int ieee80211_ifa6_changed(struct notifier_block *nb, unsigned long data, void *arg) { -@@ -1301,14 +1301,14 @@ int ieee80211_register_hw(struct ieee802 +@@ -1315,14 +1315,14 @@ int ieee80211_register_hw(struct ieee802 rtnl_unlock(); @@ -35,7 +35,7 @@ local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; result = register_inet6addr_notifier(&local->ifa6_notifier); if (result) -@@ -1317,13 +1317,13 @@ int ieee80211_register_hw(struct ieee802 +@@ -1331,13 +1331,13 @@ int ieee80211_register_hw(struct ieee802 return 0; @@ -52,7 +52,7 @@ fail_ifa: #endif wiphy_unregister(local->hw.wiphy); -@@ -1351,10 +1351,10 @@ void ieee80211_unregister_hw(struct ieee +@@ -1365,10 +1365,10 @@ void ieee80211_unregister_hw(struct ieee tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch index 80f995737b..ee49942459 100644 --- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2442,7 +2442,7 @@ static int ieee80211_scan(struct wiphy * +@@ -2444,7 +2444,7 @@ static int ieee80211_scan(struct wiphy * * the frames sent while scanning on other channel will be * lost) */ diff --git a/package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch b/package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch index d3f4aa7972..8fe8723cfe 100644 --- a/package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch +++ b/package/kernel/mac80211/patches/subsys/300-cfg80211-support-immediate-reconnect-request-hint.patch @@ -31,31 +31,9 @@ Signed-off-by: Johannes Berg /** * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -2527,6 +2527,10 @@ enum nl80211_commands { - * override mask. Used with NL80211_ATTR_S1G_CAPABILITY in - * NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT. - * -+ * @NL80211_ATTR_RECONNECT_REQUESTED: flag attribute, used with deauth and -+ * disassoc events to indicate that an immediate reconnect to the AP -+ * is desired. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3016,6 +3020,8 @@ enum nl80211_attrs { - NL80211_ATTR_S1G_CAPABILITY, - NL80211_ATTR_S1G_CAPABILITY_MASK, - -+ NL80211_ATTR_RECONNECT_REQUESTED, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -2729,7 +2729,7 @@ static void ieee80211_report_disconnect( +@@ -2734,7 +2734,7 @@ static void ieee80211_report_disconnect( }; if (tx) @@ -64,7 +42,7 @@ Signed-off-by: Johannes Berg else cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); -@@ -4716,7 +4716,8 @@ void ieee80211_mgd_quiesce(struct ieee80 +@@ -4724,7 +4724,8 @@ void ieee80211_mgd_quiesce(struct ieee80 if (ifmgd->auth_data) ieee80211_destroy_auth_data(sdata, false); cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, @@ -166,7 +144,7 @@ Signed-off-by: Johannes Berg --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -732,6 +732,7 @@ static const struct nla_policy nl80211_p +@@ -736,6 +736,7 @@ static const struct nla_policy nl80211_p NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), [NL80211_ATTR_S1G_CAPABILITY_MASK] = NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), @@ -174,7 +152,7 @@ Signed-off-by: Johannes Berg }; /* policy for the key attributes */ -@@ -15899,7 +15900,7 @@ static void nl80211_send_mlme_event(stru +@@ -15903,7 +15904,7 @@ static void nl80211_send_mlme_event(stru const u8 *buf, size_t len, enum nl80211_commands cmd, gfp_t gfp, int uapsd_queues, const u8 *req_ies, @@ -183,7 +161,7 @@ Signed-off-by: Johannes Berg { struct sk_buff *msg; void *hdr; -@@ -15921,6 +15922,9 @@ static void nl80211_send_mlme_event(stru +@@ -15925,6 +15926,9 @@ static void nl80211_send_mlme_event(stru nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies))) goto nla_put_failure; @@ -193,7 +171,7 @@ Signed-off-by: Johannes Berg if (uapsd_queues >= 0) { struct nlattr *nla_wmm = nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME); -@@ -15949,7 +15953,8 @@ void nl80211_send_rx_auth(struct cfg8021 +@@ -15953,7 +15957,8 @@ void nl80211_send_rx_auth(struct cfg8021 size_t len, gfp_t gfp) { nl80211_send_mlme_event(rdev, netdev, buf, len, @@ -203,7 +181,7 @@ Signed-off-by: Johannes Berg } void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, -@@ -15959,23 +15964,25 @@ void nl80211_send_rx_assoc(struct cfg802 +@@ -15963,23 +15968,25 @@ void nl80211_send_rx_assoc(struct cfg802 { nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE, gfp, uapsd_queues, @@ -234,7 +212,7 @@ Signed-off-by: Johannes Berg } void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, -@@ -16006,7 +16013,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct +@@ -16010,7 +16017,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1, diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch index 8f948c140e..31621ebf11 100644 --- a/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch +++ b/package/kernel/mac80211/patches/subsys/301-mac80211-support-driver-based-disconnect-with-reconn.patch @@ -34,7 +34,7 @@ Signed-off-by: Johannes Berg * @vif: &struct ieee80211_vif pointer from the add_interface callback. --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -461,7 +461,9 @@ struct ieee80211_if_managed { +@@ -450,7 +450,9 @@ struct ieee80211_if_managed { unsigned long probe_timeout; int probe_send_count; bool nullfunc_failed; @@ -47,7 +47,7 @@ Signed-off-by: Johannes Berg struct ieee80211_mgd_auth_data *auth_data; --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -2720,7 +2720,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) +@@ -2725,7 +2725,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get) static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata, const u8 *buf, size_t len, bool tx, @@ -56,7 +56,7 @@ Signed-off-by: Johannes Berg { struct ieee80211_event event = { .type = MLME_EVENT, -@@ -2729,7 +2729,7 @@ static void ieee80211_report_disconnect( +@@ -2734,7 +2734,7 @@ static void ieee80211_report_disconnect( }; if (tx) @@ -65,7 +65,7 @@ Signed-off-by: Johannes Berg else cfg80211_rx_mlme_mgmt(sdata->dev, buf, len); -@@ -2751,13 +2751,18 @@ static void __ieee80211_disconnect(struc +@@ -2756,13 +2756,18 @@ static void __ieee80211_disconnect(struc tx = !sdata->csa_block_tx; @@ -89,7 +89,7 @@ Signed-off-by: Johannes Berg tx, frame_buf); mutex_lock(&local->mtx); sdata->vif.csa_active = false; -@@ -2770,7 +2775,9 @@ static void __ieee80211_disconnect(struc +@@ -2775,7 +2780,9 @@ static void __ieee80211_disconnect(struc mutex_unlock(&local->mtx); ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx, @@ -100,7 +100,7 @@ Signed-off-by: Johannes Berg sdata_unlock(sdata); } -@@ -2789,6 +2796,13 @@ static void ieee80211_beacon_connection_ +@@ -2794,6 +2801,13 @@ static void ieee80211_beacon_connection_ sdata_info(sdata, "Connection to AP %pM lost\n", ifmgd->bssid); __ieee80211_disconnect(sdata); @@ -114,7 +114,7 @@ Signed-off-by: Johannes Berg } else { ieee80211_mgd_probe_ap(sdata, true); } -@@ -2827,6 +2841,21 @@ void ieee80211_connection_loss(struct ie +@@ -2832,6 +2846,21 @@ void ieee80211_connection_loss(struct ie } EXPORT_SYMBOL(ieee80211_connection_loss); @@ -136,7 +136,7 @@ Signed-off-by: Johannes Berg static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, bool assoc) -@@ -3130,7 +3159,7 @@ static void ieee80211_rx_mgmt_deauth(str +@@ -3135,7 +3164,7 @@ static void ieee80211_rx_mgmt_deauth(str ieee80211_set_disassoc(sdata, 0, 0, false, NULL); ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, @@ -145,7 +145,7 @@ Signed-off-by: Johannes Berg return; } -@@ -3179,7 +3208,8 @@ static void ieee80211_rx_mgmt_disassoc(s +@@ -3184,7 +3213,8 @@ static void ieee80211_rx_mgmt_disassoc(s ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -155,7 +155,7 @@ Signed-off-by: Johannes Berg } static void ieee80211_get_rates(struct ieee80211_supported_band *sband, -@@ -4199,7 +4229,8 @@ static void ieee80211_rx_mgmt_beacon(str +@@ -4204,7 +4234,8 @@ static void ieee80211_rx_mgmt_beacon(str true, deauth_buf); ieee80211_report_disconnect(sdata, deauth_buf, sizeof(deauth_buf), true, @@ -165,7 +165,7 @@ Signed-off-by: Johannes Berg return; } -@@ -4344,7 +4375,7 @@ static void ieee80211_sta_connection_los +@@ -4349,7 +4380,7 @@ static void ieee80211_sta_connection_los tx, frame_buf); ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, @@ -174,7 +174,7 @@ Signed-off-by: Johannes Berg } static int ieee80211_auth(struct ieee80211_sub_if_data *sdata) -@@ -5431,7 +5462,8 @@ int ieee80211_mgd_auth(struct ieee80211_ +@@ -5439,7 +5470,8 @@ int ieee80211_mgd_auth(struct ieee80211_ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, @@ -184,7 +184,7 @@ Signed-off-by: Johannes Berg } sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); -@@ -5503,7 +5535,8 @@ int ieee80211_mgd_assoc(struct ieee80211 +@@ -5511,7 +5543,8 @@ int ieee80211_mgd_assoc(struct ieee80211 ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, @@ -194,7 +194,7 @@ Signed-off-by: Johannes Berg } if (ifmgd->auth_data && !ifmgd->auth_data->done) { -@@ -5802,7 +5835,7 @@ int ieee80211_mgd_deauth(struct ieee8021 +@@ -5810,7 +5843,7 @@ int ieee80211_mgd_deauth(struct ieee8021 ieee80211_destroy_auth_data(sdata, false); ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, @@ -203,7 +203,7 @@ Signed-off-by: Johannes Berg return 0; } -@@ -5822,7 +5855,7 @@ int ieee80211_mgd_deauth(struct ieee8021 +@@ -5830,7 +5863,7 @@ int ieee80211_mgd_deauth(struct ieee8021 ieee80211_destroy_assoc_data(sdata, false, true); ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, @@ -212,7 +212,7 @@ Signed-off-by: Johannes Berg return 0; } -@@ -5837,7 +5870,7 @@ int ieee80211_mgd_deauth(struct ieee8021 +@@ -5845,7 +5878,7 @@ int ieee80211_mgd_deauth(struct ieee8021 req->reason_code, tx, frame_buf); ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, @@ -221,7 +221,7 @@ Signed-off-by: Johannes Berg return 0; } -@@ -5870,7 +5903,7 @@ int ieee80211_mgd_disassoc(struct ieee80 +@@ -5878,7 +5911,7 @@ int ieee80211_mgd_disassoc(struct ieee80 frame_buf); ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true, diff --git a/package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch b/package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch new file mode 100644 index 0000000000..acfdae0f5b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/302-cfg80211-Add-support-to-configure-SAE-PWE-value-to-d.patch @@ -0,0 +1,74 @@ +From: Rohan Dutta +Date: Tue, 27 Oct 2020 12:09:10 +0200 +Subject: [PATCH] cfg80211: Add support to configure SAE PWE value to drivers + +Add support to configure SAE PWE preference from userspace to drivers in +both AP and STA modes. This is needed for cases where the driver takes +care of Authentication frame processing (SME in the driver) so that +correct enforcement of the acceptable PWE derivation mechanism can be +performed. + +The userspace applications can pass the sae_pwe value using the +NL80211_ATTR_SAE_PWE attribute in the NL80211_CMD_CONNECT and +NL80211_CMD_START_AP commands to the driver. This allows selection +between the hunting-and-pecking loop and hash-to-element options for PWE +derivation. For backwards compatibility, this new attribute is optional +and if not included, the driver is notified of the value being +unspecified. + +Signed-off-by: Rohan Dutta +Signed-off-by: Jouni Malinen +Link: https://lore.kernel.org/r/20201027100910.22283-1-jouni@codeaurora.org +Signed-off-by: Johannes Berg +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1009,6 +1009,14 @@ struct survey_info { + * @sae_pwd: password for SAE authentication (for devices supporting SAE + * offload) + * @sae_pwd_len: length of SAE password (for devices supporting SAE offload) ++ * @sae_pwe: The mechanisms allowed for SAE PWE derivation ++ * NL80211_SAE_PWE_UNSPECIFIED: Not-specified, used to indicate userspace ++ * did not specify any preference. The driver should follow its ++ * internal policy in such a scenario. ++ * NL80211_SAE_PWE_HUNT_AND_PECK: Allow hunting-and-pecking loop only ++ * NL80211_SAE_PWE_HASH_TO_ELEMENT: Allow hash-to-element only ++ * NL80211_SAE_PWE_BOTH: Allow either hunting-and-pecking loop ++ * or hash-to-element + */ + struct cfg80211_crypto_settings { + u32 wpa_versions; +@@ -1027,6 +1035,7 @@ struct cfg80211_crypto_settings { + const u8 *psk; + const u8 *sae_pwd; + u8 sae_pwd_len; ++ enum nl80211_sae_pwe_mechanism sae_pwe; + }; + + /** +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -736,6 +736,9 @@ static const struct nla_policy nl80211_p + NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), + [NL80211_ATTR_S1G_CAPABILITY_MASK] = + NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), ++ [NL80211_ATTR_SAE_PWE] = ++ NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK, ++ NL80211_SAE_PWE_BOTH), + [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, + }; + +@@ -9764,6 +9767,12 @@ static int nl80211_crypto_settings(struc + nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]); + } + ++ if (info->attrs[NL80211_ATTR_SAE_PWE]) ++ settings->sae_pwe = ++ nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]); ++ else ++ settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED; ++ + return 0; + } + diff --git a/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch b/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch index f8748ef123..33dbb5eb90 100644 --- a/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch +++ b/package/kernel/mac80211/patches/subsys/311-net-fq_impl-drop-get_default_func-move-default-flow-.patch @@ -68,7 +68,7 @@ Signed-off-by: Felix Fietkau static int fq_init(struct fq *fq, int flows_cnt) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -857,7 +857,6 @@ enum txq_info_flags { +@@ -846,7 +846,6 @@ enum txq_info_flags { */ struct txq_info { struct fq_tin tin; diff --git a/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch b/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch index 09407f3b1d..b8bb2930f5 100644 --- a/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch +++ b/package/kernel/mac80211/patches/subsys/315-mac80211-add-rx-decapsulation-offload-support.patch @@ -132,7 +132,7 @@ Signed-off-by: Felix Fietkau #endif /* __MAC80211_DRIVER_OPS */ --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -839,7 +839,7 @@ static const struct net_device_ops ieee8 +@@ -835,7 +835,7 @@ static const struct net_device_ops ieee8 }; @@ -141,7 +141,7 @@ Signed-off-by: Felix Fietkau { switch (iftype) { /* P2P GO and client are mapped to AP/STATION types */ -@@ -859,7 +859,7 @@ static bool ieee80211_set_sdata_offload_ +@@ -855,7 +855,7 @@ static bool ieee80211_set_sdata_offload_ flags = sdata->vif.offload_flags; if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) && @@ -150,7 +150,7 @@ Signed-off-by: Felix Fietkau flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED; if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) && -@@ -872,10 +872,21 @@ static bool ieee80211_set_sdata_offload_ +@@ -868,10 +868,21 @@ static bool ieee80211_set_sdata_offload_ flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; } @@ -172,7 +172,7 @@ Signed-off-by: Felix Fietkau return true; } -@@ -893,7 +904,7 @@ static void ieee80211_set_vif_encap_ops( +@@ -889,7 +900,7 @@ static void ieee80211_set_vif_encap_ops( } if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) || @@ -183,7 +183,7 @@ Signed-off-by: Felix Fietkau enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED; --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -4114,7 +4114,9 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4198,7 +4198,9 @@ void ieee80211_check_fast_rx(struct sta_ .vif_type = sdata->vif.type, .control_port_protocol = sdata->control_port_protocol, }, *old, *new = NULL; @@ -193,7 +193,7 @@ Signed-off-by: Felix Fietkau /* use sparse to check that we don't return without updating */ __acquire(check_fast_rx); -@@ -4227,6 +4229,17 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4311,6 +4313,17 @@ void ieee80211_check_fast_rx(struct sta_ if (assign) new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); @@ -211,7 +211,7 @@ Signed-off-by: Felix Fietkau spin_lock_bh(&sta->lock); old = rcu_dereference_protected(sta->fast_rx, true); rcu_assign_pointer(sta->fast_rx, new); -@@ -4273,6 +4286,108 @@ void ieee80211_check_fast_rx_iface(struc +@@ -4357,6 +4370,108 @@ void ieee80211_check_fast_rx_iface(struc mutex_unlock(&local->sta_mtx); } @@ -320,7 +320,7 @@ Signed-off-by: Felix Fietkau static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, struct ieee80211_fast_rx *fast_rx) { -@@ -4293,9 +4408,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4377,9 +4492,6 @@ static bool ieee80211_invoke_fast_rx(str } addrs __aligned(2); struct ieee80211_sta_rx_stats *stats = &sta->rx_stats; @@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write * to a common data structure; drivers can implement that per queue * but we don't have that information in mac80211 -@@ -4369,32 +4481,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4453,32 +4565,6 @@ static bool ieee80211_invoke_fast_rx(str pskb_trim(skb, skb->len - fast_rx->icv_len)) goto drop; @@ -363,7 +363,7 @@ Signed-off-by: Felix Fietkau if (rx->key && !ieee80211_has_protected(hdr->frame_control)) goto drop; -@@ -4406,12 +4492,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4490,12 +4576,6 @@ static bool ieee80211_invoke_fast_rx(str return true; } @@ -376,7 +376,7 @@ Signed-off-by: Felix Fietkau /* do the header conversion - first grab the addresses */ ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); -@@ -4420,62 +4500,14 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4504,62 +4584,14 @@ static bool ieee80211_invoke_fast_rx(str /* push the addresses in front */ memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); @@ -443,7 +443,7 @@ Signed-off-by: Felix Fietkau stats->dropped++; return true; } -@@ -4529,6 +4561,47 @@ static bool ieee80211_prepare_and_rx_han +@@ -4613,6 +4645,47 @@ static bool ieee80211_prepare_and_rx_han return true; } @@ -491,7 +491,7 @@ Signed-off-by: Felix Fietkau /* * This is the actual Rx frames handler. as it belongs to Rx path it must * be called with rcu_read_lock protection. -@@ -4766,15 +4839,20 @@ void ieee80211_rx_list(struct ieee80211_ +@@ -4850,15 +4923,20 @@ void ieee80211_rx_list(struct ieee80211_ * if it was previously present. * Also, frames with less than 16 bytes are dropped. */ 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 new file mode 100644 index 0000000000..4be011ffec --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/316-mac80211-enable-QoS-support-for-nl80211-ctrl-port.patch @@ -0,0 +1,116 @@ +From: Markus Theil +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 +Signed-off-by: Markus Theil +Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de +Signed-off-by: Johannes Berg +--- + +--- 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)) +@@ -5421,6 +5419,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; +@@ -5443,8 +5442,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); +@@ -5461,10 +5459,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/320-mac80211_hwsim-add-6GHz-channels.patch b/package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch new file mode 100644 index 0000000000..a7c09f00bc --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/320-mac80211_hwsim-add-6GHz-channels.patch @@ -0,0 +1,123 @@ +From: Ramon Fontes +Date: Sun, 27 Dec 2020 00:11:55 -0300 +Subject: [PATCH] mac80211_hwsim: add 6GHz channels + +Advertise 6GHz channels to mac80211. + +Signed-off-by: Ramon Fontes +Link: https://lore.kernel.org/r/20201227031155.81161-1-ramonreisfontes@gmail.com +[reword commit message] +Signed-off-by: Johannes Berg +--- + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -311,6 +311,12 @@ static struct net_device *hwsim_mon; /* + .hw_value = (_freq), \ + } + ++#define CHAN6G(_freq) { \ ++ .band = NL80211_BAND_6GHZ, \ ++ .center_freq = (_freq), \ ++ .hw_value = (_freq), \ ++} ++ + static const struct ieee80211_channel hwsim_channels_2ghz[] = { + CHAN2G(2412), /* Channel 1 */ + CHAN2G(2417), /* Channel 2 */ +@@ -377,6 +383,68 @@ static const struct ieee80211_channel hw + CHAN5G(5925), /* Channel 185 */ + }; + ++static const struct ieee80211_channel hwsim_channels_6ghz[] = { ++ CHAN6G(5955), /* Channel 1 */ ++ CHAN6G(5975), /* Channel 5 */ ++ CHAN6G(5995), /* Channel 9 */ ++ CHAN6G(6015), /* Channel 13 */ ++ CHAN6G(6035), /* Channel 17 */ ++ CHAN6G(6055), /* Channel 21 */ ++ CHAN6G(6075), /* Channel 25 */ ++ CHAN6G(6095), /* Channel 29 */ ++ CHAN6G(6115), /* Channel 33 */ ++ CHAN6G(6135), /* Channel 37 */ ++ CHAN6G(6155), /* Channel 41 */ ++ CHAN6G(6175), /* Channel 45 */ ++ CHAN6G(6195), /* Channel 49 */ ++ CHAN6G(6215), /* Channel 53 */ ++ CHAN6G(6235), /* Channel 57 */ ++ CHAN6G(6255), /* Channel 61 */ ++ CHAN6G(6275), /* Channel 65 */ ++ CHAN6G(6295), /* Channel 69 */ ++ CHAN6G(6315), /* Channel 73 */ ++ CHAN6G(6335), /* Channel 77 */ ++ CHAN6G(6355), /* Channel 81 */ ++ CHAN6G(6375), /* Channel 85 */ ++ CHAN6G(6395), /* Channel 89 */ ++ CHAN6G(6415), /* Channel 93 */ ++ CHAN6G(6435), /* Channel 97 */ ++ CHAN6G(6455), /* Channel 181 */ ++ CHAN6G(6475), /* Channel 105 */ ++ CHAN6G(6495), /* Channel 109 */ ++ CHAN6G(6515), /* Channel 113 */ ++ CHAN6G(6535), /* Channel 117 */ ++ CHAN6G(6555), /* Channel 121 */ ++ CHAN6G(6575), /* Channel 125 */ ++ CHAN6G(6595), /* Channel 129 */ ++ CHAN6G(6615), /* Channel 133 */ ++ CHAN6G(6635), /* Channel 137 */ ++ CHAN6G(6655), /* Channel 141 */ ++ CHAN6G(6675), /* Channel 145 */ ++ CHAN6G(6695), /* Channel 149 */ ++ CHAN6G(6715), /* Channel 153 */ ++ CHAN6G(6735), /* Channel 157 */ ++ CHAN6G(6755), /* Channel 161 */ ++ CHAN6G(6775), /* Channel 165 */ ++ CHAN6G(6795), /* Channel 169 */ ++ CHAN6G(6815), /* Channel 173 */ ++ CHAN6G(6835), /* Channel 177 */ ++ CHAN6G(6855), /* Channel 181 */ ++ CHAN6G(6875), /* Channel 185 */ ++ CHAN6G(6895), /* Channel 189 */ ++ CHAN6G(6915), /* Channel 193 */ ++ CHAN6G(6935), /* Channel 197 */ ++ CHAN6G(6955), /* Channel 201 */ ++ CHAN6G(6975), /* Channel 205 */ ++ CHAN6G(6995), /* Channel 209 */ ++ CHAN6G(7015), /* Channel 213 */ ++ CHAN6G(7035), /* Channel 217 */ ++ CHAN6G(7055), /* Channel 221 */ ++ CHAN6G(7075), /* Channel 225 */ ++ CHAN6G(7095), /* Channel 229 */ ++ CHAN6G(7115), /* Channel 233 */ ++}; ++ + #define NUM_S1G_CHANS_US 51 + static struct ieee80211_channel hwsim_channels_s1g[NUM_S1G_CHANS_US]; + +@@ -548,6 +616,7 @@ struct mac80211_hwsim_data { + struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; + struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)]; + struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; ++ struct ieee80211_channel channels_6ghz[ARRAY_SIZE(hwsim_channels_6ghz)]; + struct ieee80211_channel channels_s1g[ARRAY_SIZE(hwsim_channels_s1g)]; + struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; + struct ieee80211_iface_combination if_combination; +@@ -578,7 +647,8 @@ struct mac80211_hwsim_data { + struct ieee80211_channel *channel; + unsigned long next_start, start, end; + } survey_data[ARRAY_SIZE(hwsim_channels_2ghz) + +- ARRAY_SIZE(hwsim_channels_5ghz)]; ++ ARRAY_SIZE(hwsim_channels_5ghz) + ++ ARRAY_SIZE(hwsim_channels_6ghz)]; + + struct ieee80211_channel *channel; + u64 beacon_int /* beacon interval in us */; +@@ -3149,6 +3219,8 @@ static int mac80211_hwsim_new_radio(stru + sizeof(hwsim_channels_2ghz)); + memcpy(data->channels_5ghz, hwsim_channels_5ghz, + sizeof(hwsim_channels_5ghz)); ++ memcpy(data->channels_6ghz, hwsim_channels_6ghz, ++ sizeof(hwsim_channels_6ghz)); + memcpy(data->channels_s1g, hwsim_channels_s1g, + sizeof(hwsim_channels_s1g)); + memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch b/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch new file mode 100644 index 0000000000..4bac10eefe --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/321-mac80211_hwsim-make-6-GHz-channels-usable.patch @@ -0,0 +1,74 @@ +From: Felix Fietkau +Date: Mon, 24 May 2021 11:46:09 +0200 +Subject: [PATCH] mac80211_hwsim: make 6 GHz channels usable + +The previous commit that claimed to add 6 GHz channels didn't actually make +them usable, since the 6 GHz band was not registered with mac80211. + +Fixes: 28881922abd7 ("mac80211_hwsim: add 6GHz channels") +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -2968,15 +2968,19 @@ static void mac80211_hwsim_he_capab(stru + { + u16 n_iftype_data; + +- if (sband->band == NL80211_BAND_2GHZ) { ++ switch (sband->band) { ++ case NL80211_BAND_2GHZ: + n_iftype_data = ARRAY_SIZE(he_capa_2ghz); + sband->iftype_data = + (struct ieee80211_sband_iftype_data *)he_capa_2ghz; +- } else if (sband->band == NL80211_BAND_5GHZ) { ++ break; ++ case NL80211_BAND_5GHZ: ++ case NL80211_BAND_6GHZ: + n_iftype_data = ARRAY_SIZE(he_capa_5ghz); + sband->iftype_data = + (struct ieee80211_sband_iftype_data *)he_capa_5ghz; +- } else { ++ break; ++ default: + return; + } + +@@ -3265,6 +3269,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; ++ case NL80211_BAND_6GHZ: ++ sband->channels = data->channels_6ghz; ++ sband->n_channels = ARRAY_SIZE(hwsim_channels_6ghz); ++ sband->bitrates = data->rates + 4; ++ sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; ++ break; + case NL80211_BAND_S1GHZ: + memcpy(&sband->s1g_cap, &hwsim_s1g_cap, + sizeof(sband->s1g_cap)); +@@ -3275,6 +3285,13 @@ static int mac80211_hwsim_new_radio(stru + continue; + } + ++ mac80211_hwsim_he_capab(sband); ++ ++ hw->wiphy->bands[band] = sband; ++ ++ if (band == NL80211_BAND_6GHZ) ++ continue; ++ + sband->ht_cap.ht_supported = true; + sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | +@@ -3288,10 +3305,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; +- +- mac80211_hwsim_he_capab(sband); +- +- hw->wiphy->bands[band] = sband; + } + + /* By default all radios belong to the first group */ 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 index 96ee595ac1..1cab2eb194 100644 --- 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 @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile -@@ -55,11 +55,9 @@ mac80211-$(CONFIG_PM) += pm.o +@@ -56,11 +56,9 @@ mac80211-$(CONFIG_PM) += pm.o CFLAGS_trace.o := -I$(src) rc80211_minstrel-y := \ diff --git a/package/kernel/mac80211/patches/subsys/353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch b/package/kernel/mac80211/patches/subsys/353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch new file mode 100644 index 0000000000..0d475b7329 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/353-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Wed, 28 Apr 2021 21:03:13 +0200 +Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro + +Add missing braces to avoid issues with e.g. using additions in the +div expression + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -14,7 +14,7 @@ + + /* scaled fraction values */ + #define MINSTREL_SCALE 12 +-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) ++#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div)) + #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) + + #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ diff --git a/package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch b/package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch deleted file mode 100644 index 0b7c8dd49b..0000000000 --- a/package/kernel/mac80211/patches/subsys/370-mac80211-fix-TXQ-AC-confusion.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Johannes Berg -Date: Tue, 23 Mar 2021 21:05:01 +0100 -Subject: [PATCH] mac80211: fix TXQ AC confusion - -Normally, TXQs have - - txq->tid = tid; - txq->ac = ieee80211_ac_from_tid(tid); - -However, the special management TXQ actually has - - txq->tid = IEEE80211_NUM_TIDS; // 16 - txq->ac = IEEE80211_AC_VO; - -This makes sense, but ieee80211_ac_from_tid(16) is the same -as ieee80211_ac_from_tid(0) which is just IEEE80211_AC_BE. - -Now, normally this is fine. However, if the netdev queues -were stopped, then the code in ieee80211_tx_dequeue() will -propagate the stop from the interface (vif->txqs_stopped[]) -if the AC 2 (ieee80211_ac_from_tid(txq->tid)) is marked as -stopped. On wake, however, __ieee80211_wake_txqs() will wake -the TXQ if AC 0 (txq->ac) is woken up. - -If a driver stops all queues with ieee80211_stop_tx_queues() -and then wakes them again with ieee80211_wake_tx_queues(), -the ieee80211_wake_txqs() tasklet will run to resync queue -and TXQ state. If all queues were woken, then what'll happen -is that _ieee80211_wake_txqs() will run in order of HW queues -0-3, typically (and certainly for iwlwifi) corresponding to -ACs 0-3, so it'll call __ieee80211_wake_txqs() for each AC in -order 0-3. - -When __ieee80211_wake_txqs() is called for AC 0 (VO) that'll -wake up the management TXQ (remember its tid is 16), and the -driver's wake_tx_queue() will be called. That tries to get a -frame, which will immediately *stop* the TXQ again, because -now we check against AC 2, and AC 2 hasn't yet been marked as -woken up again in sdata->vif.txqs_stopped[] since we're only -in the __ieee80211_wake_txqs() call for AC 0. - -Thus, the management TXQ will never be started again. - -Fix this by checking txq->ac directly instead of calculating -the AC as ieee80211_ac_from_tid(txq->tid). - -Fixes: adf8ed01e4fd ("mac80211: add an optional TXQ for other PS-buffered frames") -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3589,7 +3589,7 @@ begin: - test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags)) - goto out; - -- if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) { -+ if (vif->txqs_stopped[txq->ac]) { - set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags); - goto out; - } 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 index b439a3814c..8d094a3632 100644 --- 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 @@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg * * Transmit and frame generation functions. */ -@@ -1403,8 +1403,17 @@ static void ieee80211_txq_enqueue(struct +@@ -1401,8 +1401,17 @@ static void ieee80211_txq_enqueue(struct ieee80211_set_skb_enqueue_time(skb); spin_lock_bh(&fq->lock); @@ -48,7 +48,7 @@ Signed-off-by: Johannes Berg spin_unlock_bh(&fq->lock); } -@@ -3846,6 +3855,9 @@ bool ieee80211_txq_airtime_check(struct +@@ -3844,6 +3853,9 @@ bool ieee80211_txq_airtime_check(struct if (!txq->sta) return true; diff --git a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch index 4d8a91a413..5bc1469a3f 100644 --- a/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch +++ b/package/kernel/mac80211/patches/subsys/372-mac80211-set-sk_pacing_shift-for-802.3-txpath.patch @@ -9,7 +9,7 @@ Signed-off-by: Lorenzo Bianconi --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4173,6 +4173,9 @@ static bool ieee80211_tx_8023(struct iee +@@ -4171,6 +4171,9 @@ static bool ieee80211_tx_8023(struct iee unsigned long flags; int q = info->hw_queue; diff --git a/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch b/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch index c432d77b2e..117fb35fcf 100644 --- a/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch +++ b/package/kernel/mac80211/patches/subsys/373-mac80211-support-Rx-timestamp-calculation-for-all-pr.patch @@ -15,7 +15,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1600,13 +1600,8 @@ ieee80211_have_rx_timestamp(struct ieee8 +@@ -1587,13 +1587,8 @@ ieee80211_have_rx_timestamp(struct ieee8 { WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START && status->flag & RX_FLAG_MACTIME_END); diff --git a/package/kernel/mac80211/patches/subsys/374-mac80211-fix-time-is-after-bug-in-mlme.patch b/package/kernel/mac80211/patches/subsys/374-mac80211-fix-time-is-after-bug-in-mlme.patch deleted file mode 100644 index 0573aece64..0000000000 --- a/package/kernel/mac80211/patches/subsys/374-mac80211-fix-time-is-after-bug-in-mlme.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Ben Greear -Date: Tue, 30 Mar 2021 16:07:49 -0700 -Subject: [PATCH] mac80211: fix time-is-after bug in mlme - -The incorrect timeout check caused probing to happen when it did -not need to happen. This in turn caused tx performance drop -for around 5 seconds in ath10k-ct driver. Possibly that tx drop -is due to a secondary issue, but fixing the probe to not happen -when traffic is running fixes the symptom. - -Signed-off-by: Ben Greear -Fixes: 9abf4e49830d ("mac80211: optimize station connection monitor") -Acked-by: Felix Fietkau -Link: https://lore.kernel.org/r/20210330230749.14097-1-greearb@candelatech.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/mlme.c -+++ b/net/mac80211/mlme.c -@@ -4691,7 +4691,10 @@ static void ieee80211_sta_conn_mon_timer - timeout = sta->rx_stats.last_rx; - timeout += IEEE80211_CONNECTION_IDLE_TIME; - -- if (time_is_before_jiffies(timeout)) { -+ /* If timeout is after now, then update timer to fire at -+ * the later date, but do not actually probe at this time. -+ */ -+ if (time_is_after_jiffies(timeout)) { - mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout)); - return; - } diff --git a/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch b/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch new file mode 100644 index 0000000000..031f8e1636 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/374-mac80211-move-A-MPDU-session-check-from-minstrel_ht-.patch @@ -0,0 +1,126 @@ +From: Felix Fietkau +Date: Thu, 17 Jun 2021 17:56:54 +0200 +Subject: [PATCH] mac80211: move A-MPDU session check from minstrel_ht to + mac80211 + +This avoids calling back into tx handlers from within the rate control module. +Preparation for deferring rate control until tx dequeue + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6160,6 +6160,11 @@ enum rate_control_capabilities { + * otherwise the NSS difference doesn't bother us. + */ + RATE_CTRL_CAPA_VHT_EXT_NSS_BW = BIT(0), ++ /** ++ * @RATE_CTRL_CAPA_AMPDU_TRIGGER: ++ * mac80211 should start A-MPDU sessions on tx ++ */ ++ RATE_CTRL_CAPA_AMPDU_TRIGGER = BIT(1), + }; + + struct rate_control_ops { +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1153,29 +1153,6 @@ minstrel_downgrade_prob_rate(struct mins + } + + static void +-minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb) +-{ +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +- struct sta_info *sta = container_of(pubsta, struct sta_info, sta); +- u16 tid; +- +- if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) +- return; +- +- if (unlikely(!ieee80211_is_data_qos(hdr->frame_control))) +- return; +- +- if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) +- return; +- +- tid = ieee80211_get_tid(hdr); +- if (likely(sta->ampdu_mlme.tid_tx[tid])) +- return; +- +- ieee80211_start_tx_ba_session(pubsta, tid, 0); +-} +- +-static void + minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, + void *priv_sta, struct ieee80211_tx_status *st) + { +@@ -1477,10 +1454,6 @@ minstrel_ht_get_rate(void *priv, struct + struct minstrel_priv *mp = priv; + u16 sample_idx; + +- if (!(info->flags & IEEE80211_TX_CTL_AMPDU) && +- !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate))) +- minstrel_aggr_check(sta, txrc->skb); +- + info->flags |= mi->tx_flags; + + #ifdef CPTCFG_MAC80211_DEBUGFS +@@ -1894,6 +1867,7 @@ static u32 minstrel_ht_get_expected_thro + + static const struct rate_control_ops mac80211_minstrel_ht = { + .name = "minstrel_ht", ++ .capa = RATE_CTRL_CAPA_AMPDU_TRIGGER, + .tx_status_ext = minstrel_ht_tx_status, + .get_rate = minstrel_ht_get_rate, + .rate_init = minstrel_ht_rate_init, +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3931,6 +3931,29 @@ void ieee80211_txq_schedule_start(struct + } + EXPORT_SYMBOL(ieee80211_txq_schedule_start); + ++static void ++ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, ++ struct sk_buff *skb) ++{ ++ struct rate_control_ref *ref = sdata->local->rate_ctrl; ++ u16 tid; ++ ++ if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) ++ return; ++ ++ if (!sta || !sta->sta.ht_cap.ht_supported || ++ !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || ++ skb->protocol == sdata->control_port_protocol) ++ return; ++ ++ tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; ++ if (likely(sta->ampdu_mlme.tid_tx[tid])) ++ return; ++ ++ ieee80211_start_tx_ba_session(&sta->sta, tid, 0); ++} ++ + void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags, +@@ -3961,6 +3984,8 @@ void __ieee80211_subif_start_xmit(struct + skb_get_hash(skb); + } + ++ ieee80211_aggr_check(sdata, sta, skb); ++ + if (sta) { + struct ieee80211_fast_tx *fast_tx; + +@@ -4224,6 +4249,8 @@ static void ieee80211_8023_xmit(struct i + + memset(info, 0, sizeof(*info)); + ++ ieee80211_aggr_check(sdata, sta, skb); ++ + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); + if (tid_tx) { diff --git a/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch b/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch new file mode 100644 index 0000000000..cf84fca68a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/375-mac80211-call-ieee80211_tx_h_rate_ctrl-when-dequeue.patch @@ -0,0 +1,114 @@ +From: Ryder Lee +Date: Fri, 28 May 2021 14:05:41 +0800 +Subject: [PATCH] mac80211: call ieee80211_tx_h_rate_ctrl() when dequeue + +Make ieee80211_tx_h_rate_ctrl() get called on dequeue to improve +performance since it reduces the turnaround time for rate control. + +Signed-off-by: Ryder Lee +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1778,8 +1778,6 @@ static int invoke_tx_handlers_early(stru + CALL_TXH(ieee80211_tx_h_ps_buf); + CALL_TXH(ieee80211_tx_h_check_control_port_protocol); + CALL_TXH(ieee80211_tx_h_select_key); +- if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL)) +- CALL_TXH(ieee80211_tx_h_rate_ctrl); + + txh_done: + if (unlikely(res == TX_DROP)) { +@@ -1812,6 +1810,9 @@ static int invoke_tx_handlers_late(struc + goto txh_done; + } + ++ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL)) ++ CALL_TXH(ieee80211_tx_h_rate_ctrl); ++ + CALL_TXH(ieee80211_tx_h_michael_mic_add); + CALL_TXH(ieee80211_tx_h_sequence); + CALL_TXH(ieee80211_tx_h_fragment); +@@ -3382,15 +3383,21 @@ out: + * Can be called while the sta lock is held. Anything that can cause packets to + * be generated will cause deadlock! + */ +-static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata, +- struct sta_info *sta, u8 pn_offs, +- struct ieee80211_key *key, +- struct sk_buff *skb) ++static ieee80211_tx_result ++ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, u8 pn_offs, ++ struct ieee80211_key *key, ++ struct ieee80211_tx_data *tx) + { ++ struct sk_buff *skb = tx->skb; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + u8 tid = IEEE80211_NUM_TIDS; + ++ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL) && ++ ieee80211_tx_h_rate_ctrl(tx) != TX_CONTINUE) ++ return TX_DROP; ++ + if (key) + info->control.hw_key = &key->conf; + +@@ -3439,6 +3446,8 @@ static void ieee80211_xmit_fast_finish(s + break; + } + } ++ ++ return TX_CONTINUE; + } + + static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, +@@ -3542,24 +3551,17 @@ static bool ieee80211_xmit_fast(struct i + tx.sta = sta; + tx.key = fast_tx->key; + +- if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { +- tx.skb = skb; +- r = ieee80211_tx_h_rate_ctrl(&tx); +- skb = tx.skb; +- tx.skb = NULL; +- +- if (r != TX_CONTINUE) { +- if (r != TX_QUEUED) +- kfree_skb(skb); +- return true; +- } +- } +- + if (ieee80211_queue_skb(local, sdata, sta, skb)) + return true; + +- ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, +- fast_tx->key, skb); ++ tx.skb = skb; ++ r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, ++ fast_tx->key, &tx); ++ tx.skb = NULL; ++ if (r == TX_DROP) { ++ kfree_skb(skb); ++ return true; ++ } + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, +@@ -3670,8 +3672,12 @@ begin: + (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) + pn_offs = ieee80211_hdrlen(hdr->frame_control); + +- ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, +- tx.key, skb); ++ r = ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, ++ tx.key, &tx); ++ if (r != TX_CONTINUE) { ++ ieee80211_free_txskb(&local->hw, skb); ++ goto begin; ++ } + } else { + if (invoke_tx_handlers_late(&tx)) + goto begin; diff --git a/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch new file mode 100644 index 0000000000..43a4a1334d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/376-mac80211-add-rate-control-support-for-encap-offload.patch @@ -0,0 +1,119 @@ +From: Ryder Lee +Date: Fri, 28 May 2021 14:05:43 +0800 +Subject: [PATCH] mac80211: add rate control support for encap offload + +The software rate control cannot deal with encap offload, so fix it. + +Signed-off-by: Ryder Lee +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2024,6 +2024,15 @@ static inline void ieee80211_tx_skb(stru + ieee80211_tx_skb_tid(sdata, skb, 7); + } + ++static inline bool ieee80211_is_tx_data(struct sk_buff *skb) ++{ ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ ++ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP || ++ ieee80211_is_data(hdr->frame_control); ++} ++ + u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + struct ieee802_11_elems *elems, + u64 filter, u32 crc, u8 *transmitter_bssid, +--- a/net/mac80211/rate.c ++++ b/net/mac80211/rate.c +@@ -297,15 +297,11 @@ void ieee80211_check_rate_mask(struct ie + static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc) + { + struct sk_buff *skb = txrc->skb; +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- __le16 fc; +- +- fc = hdr->frame_control; + + return (info->flags & (IEEE80211_TX_CTL_NO_ACK | + IEEE80211_TX_CTL_USE_MINRATE)) || +- !ieee80211_is_data(fc); ++ !ieee80211_is_tx_data(skb); + } + + static void rc_send_low_basicrate(struct ieee80211_tx_rate *rate, +@@ -870,7 +866,6 @@ void ieee80211_get_tx_rates(struct ieee8 + int max_rates) + { + struct ieee80211_sub_if_data *sdata; +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_supported_band *sband; + +@@ -882,7 +877,7 @@ void ieee80211_get_tx_rates(struct ieee8 + sdata = vif_to_sdata(vif); + sband = sdata->local->hw.wiphy->bands[info->band]; + +- if (ieee80211_is_data(hdr->frame_control)) ++ if (ieee80211_is_tx_data(skb)) + rate_control_apply_mask(sdata, sta, sband, dest, max_rates); + + if (dest[0].idx < 0) +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -679,6 +679,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 + u32 len; + struct ieee80211_tx_rate_control txrc; + struct ieee80211_sta_rates *ratetbl = NULL; ++ bool encap = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; + bool assoc = false; + + memset(&txrc, 0, sizeof(txrc)); +@@ -720,7 +721,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 + * just wants a probe response. + */ + if (tx->sdata->vif.bss_conf.use_short_preamble && +- (ieee80211_is_data(hdr->frame_control) || ++ (ieee80211_is_tx_data(tx->skb) || + (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) + txrc.short_preamble = true; + +@@ -742,7 +743,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 + "%s: Dropped data frame as no usable bitrate found while " + "scanning and associated. Target station: " + "%pM on %d GHz band\n", +- tx->sdata->name, hdr->addr1, ++ tx->sdata->name, ++ encap ? ((struct ethhdr *)hdr)->h_dest : hdr->addr1, + info->band ? 5 : 2)) + return TX_DROP; + +@@ -776,7 +778,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 + + if (txrc.reported_rate.idx < 0) { + txrc.reported_rate = tx->rate; +- if (tx->sta && ieee80211_is_data(hdr->frame_control)) ++ if (tx->sta && ieee80211_is_tx_data(tx->skb)) + tx->sta->tx_stats.last_rate = txrc.reported_rate; + } else if (tx->sta) + tx->sta->tx_stats.last_rate = txrc.reported_rate; +@@ -3660,8 +3662,16 @@ begin: + else + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + +- if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) ++ if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { ++ if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { ++ r = ieee80211_tx_h_rate_ctrl(&tx); ++ if (r != TX_CONTINUE) { ++ ieee80211_free_txskb(&local->hw, skb); ++ goto begin; ++ } ++ } + goto encap_out; ++ } + + if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) { + struct sta_info *sta = container_of(txq->sta, struct sta_info, diff --git a/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch b/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch new file mode 100644 index 0000000000..d4b327c69c --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/377-mac80211-minstrel_ht-fix-sample-time-check.patch @@ -0,0 +1,23 @@ +From: Felix Fietkau +Date: Thu, 17 Jun 2021 12:05:54 +0200 +Subject: [PATCH] mac80211: minstrel_ht: fix sample time check + +We need to skip sampling if the next sample time is after jiffies, not before. +This patch fixes an issue where in some cases only very little sampling (or none +at all) is performed, leading to really bad data rates + +Fixes: 80d55154b2f8 ("mac80211: minstrel_ht: significantly redesign the rate probing strategy") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1466,7 +1466,7 @@ minstrel_ht_get_rate(void *priv, struct + (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) + return; + +- if (time_is_before_jiffies(mi->sample_time)) ++ if (time_is_after_jiffies(mi->sample_time)) + return; + + mi->sample_time = jiffies + MINSTREL_SAMPLE_INTERVAL; diff --git a/package/kernel/mac80211/patches/subsys/378-mac80211-remove-iwlwifi-specific-workaround-that-bro.patch b/package/kernel/mac80211/patches/subsys/378-mac80211-remove-iwlwifi-specific-workaround-that-bro.patch new file mode 100644 index 0000000000..a5ad377e6f --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/378-mac80211-remove-iwlwifi-specific-workaround-that-bro.patch @@ -0,0 +1,51 @@ +From: Felix Fietkau +Date: Sat, 19 Jun 2021 12:10:14 +0200 +Subject: [PATCH] mac80211: remove iwlwifi specific workaround that broke sta + NDP tx + +Sending nulldata packets is important for sw AP link probing and detecting +4-address mode links. The checks that dropped these packets were apparently +added to work around an iwlwifi firmware bug with multi-TID aggregation. + +Fixes: 41cbb0f5a295 ("mac80211: add support for HE") +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +@@ -1085,6 +1085,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mv + if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_INVALID_STA)) + return -1; + ++ if (unlikely(ieee80211_is_any_nullfunc(fc)) && sta->he_cap.has_he) ++ return -1; ++ + if (unlikely(ieee80211_is_probe_resp(fc))) + iwl_mvm_probe_resp_set_noa(mvm, skb); + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1094,11 +1094,6 @@ void ieee80211_send_nullfunc(struct ieee + struct ieee80211_hdr_3addr *nullfunc; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + +- /* Don't send NDPs when STA is connected HE */ +- if (sdata->vif.type == NL80211_IFTYPE_STATION && +- !(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) +- return; +- + skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, + !ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP)); + if (!skb) +@@ -1130,10 +1125,6 @@ static void ieee80211_send_4addr_nullfun + if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) + return; + +- /* Don't send NDPs when connected HE */ +- if (!(sdata->u.mgd.flags & IEEE80211_STA_DISABLE_HE)) +- return; +- + skb = dev_alloc_skb(local->hw.extra_tx_headroom + 30); + if (!skb) + return; diff --git a/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch b/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch new file mode 100644 index 0000000000..2ad083f150 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/379-mac80211-fix-starting-aggregation-sessions-on-mesh-i.patch @@ -0,0 +1,112 @@ +From: Felix Fietkau +Date: Tue, 29 Jun 2021 13:25:09 +0200 +Subject: [PATCH] mac80211: fix starting aggregation sessions on mesh + interfaces + +The logic for starting aggregation sessions was recently moved from minstrel_ht +to mac80211, into the subif tx handler just after the sta lookup. +Unfortunately this didn't work for mesh interfaces, since the sta lookup is +deferred until a much later point in time on those. +Fix this by also calling the aggregation check right after the deferred sta +lookup. + +Fixes: 08a46c642001 ("mac80211: move A-MPDU session check from minstrel_ht to mac80211") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1159,6 +1159,29 @@ static bool ieee80211_tx_prep_agg(struct + return queued; + } + ++static void ++ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, ++ struct sk_buff *skb) ++{ ++ struct rate_control_ref *ref = sdata->local->rate_ctrl; ++ u16 tid; ++ ++ if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) ++ return; ++ ++ if (!sta || !sta->sta.ht_cap.ht_supported || ++ !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || ++ skb->protocol == sdata->control_port_protocol) ++ return; ++ ++ tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; ++ if (likely(sta->ampdu_mlme.tid_tx[tid])) ++ return; ++ ++ ieee80211_start_tx_ba_session(&sta->sta, tid, 0); ++} ++ + /* + * initialises @tx + * pass %NULL for the station if unknown, a valid pointer if known +@@ -1172,6 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su + struct ieee80211_local *local = sdata->local; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ bool aggr_check = false; + int tid; + + memset(tx, 0, sizeof(*tx)); +@@ -1200,8 +1224,10 @@ ieee80211_tx_prepare(struct ieee80211_su + } 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)) ++ if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) { + tx->sta = sta_info_get(sdata, hdr->addr1); ++ aggr_check = true; ++ } + } + + if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && +@@ -1211,8 +1237,12 @@ ieee80211_tx_prepare(struct ieee80211_su + struct tid_ampdu_tx *tid_tx; + + tid = ieee80211_get_tid(hdr); +- + tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); ++ if (!tid_tx && aggr_check) { ++ ieee80211_aggr_check(sdata, tx->sta, skb); ++ tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]); ++ } ++ + if (tid_tx) { + bool queued; + +@@ -3947,29 +3977,6 @@ void ieee80211_txq_schedule_start(struct + } + EXPORT_SYMBOL(ieee80211_txq_schedule_start); + +-static void +-ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, +- struct sta_info *sta, +- struct sk_buff *skb) +-{ +- struct rate_control_ref *ref = sdata->local->rate_ctrl; +- u16 tid; +- +- if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER)) +- return; +- +- if (!sta || !sta->sta.ht_cap.ht_supported || +- !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO || +- skb->protocol == sdata->control_port_protocol) +- return; +- +- tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; +- if (likely(sta->ampdu_mlme.tid_tx[tid])) +- return; +- +- ieee80211_start_tx_ba_session(&sta->sta, tid, 0); +-} +- + void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags, diff --git a/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch b/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch new file mode 100644 index 0000000000..b21b671c10 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/380-mac80211-introduce-aql_enable-node-in-debugfs.patch @@ -0,0 +1,111 @@ +From: Lorenzo Bianconi +Date: Sat, 9 Jan 2021 18:57:51 +0100 +Subject: [PATCH] mac80211: introduce aql_enable node in debugfs + +Introduce aql_enable node in debugfs in order to enable/disable aql. +This is useful for debugging purpose. + +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/e7a934d5d84e4796c4f97ea5de4e66c824296b07.1610214851.git.lorenzo@kernel.org +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -281,6 +281,56 @@ static const struct file_operations aql_ + .llseek = default_llseek, + }; + ++static ssize_t aql_enable_read(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ char buf[3]; ++ int len; ++ ++ len = scnprintf(buf, sizeof(buf), "%d\n", ++ !static_key_false(&aql_disable.key)); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t aql_enable_write(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ bool aql_disabled = static_key_false(&aql_disable.key); ++ char buf[3]; ++ size_t len; ++ ++ if (count > sizeof(buf)) ++ return -EINVAL; ++ ++ if (copy_from_user(buf, user_buf, count)) ++ return -EFAULT; ++ ++ buf[sizeof(buf) - 1] = '\0'; ++ len = strlen(buf); ++ if (len > 0 && buf[len - 1] == '\n') ++ buf[len - 1] = 0; ++ ++ if (buf[0] == '0' && buf[1] == '\0') { ++ if (!aql_disabled) ++ static_branch_inc(&aql_disable); ++ } else if (buf[0] == '1' && buf[1] == '\0') { ++ if (aql_disabled) ++ static_branch_dec(&aql_disable); ++ } else { ++ return -EINVAL; ++ } ++ ++ return count; ++} ++ ++static const struct file_operations aql_enable_ops = { ++ .write = aql_enable_write, ++ .read = aql_enable_read, ++ .open = simple_open, ++ .llseek = default_llseek, ++}; ++ + static ssize_t force_tx_status_read(struct file *file, + char __user *user_buf, + size_t count, +@@ -569,6 +619,7 @@ void debugfs_hw_add(struct ieee80211_loc + DEBUGFS_ADD(power); + DEBUGFS_ADD(hw_conf); + DEBUGFS_ADD_MODE(force_tx_status, 0600); ++ DEBUGFS_ADD_MODE(aql_enable, 0600); + + if (local->ops->wake_tx_queue) + DEBUGFS_ADD_MODE(aqm, 0600); +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1140,6 +1140,8 @@ enum mac80211_scan_state { + SCAN_ABORT, + }; + ++DECLARE_STATIC_KEY_FALSE(aql_disable); ++ + struct ieee80211_local { + /* embed the driver visible part. + * don't cast (use the static inlines below), but we keep +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3887,6 +3887,8 @@ void __ieee80211_schedule_txq(struct iee + } + EXPORT_SYMBOL(__ieee80211_schedule_txq); + ++DEFINE_STATIC_KEY_FALSE(aql_disable); ++ + bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) + { +@@ -3896,6 +3898,9 @@ bool ieee80211_txq_airtime_check(struct + if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) + return true; + ++ if (static_branch_unlikely(&aql_disable)) ++ return true; ++ + if (!txq->sta) + return true; + diff --git a/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch b/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch new file mode 100644 index 0000000000..708ad6f460 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/381-mac80211-rearrange-struct-txq_info-for-fewer-holes.patch @@ -0,0 +1,39 @@ +From: Johannes Berg +Date: Fri, 18 Jun 2021 13:41:44 +0300 +Subject: [PATCH] mac80211: rearrange struct txq_info for fewer holes + +We can slightly decrease the size of struct txq_info by +rearranging some fields for fewer holes, so do that. + +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Link: https://lore.kernel.org/r/iwlwifi.20210618133832.1bf019a1fe2e.Ib54622b8d6dc1a9a7dc484e573c073119450538b@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -5,7 +5,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2007-2010 Johannes Berg + * Copyright 2013-2015 Intel Mobile Communications GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #ifndef IEEE80211_I_H +@@ -848,9 +848,12 @@ struct txq_info { + struct fq_tin tin; + struct codel_vars def_cvars; + struct codel_stats cstats; +- struct sk_buff_head frags; +- struct list_head schedule_order; ++ + u16 schedule_round; ++ struct list_head schedule_order; ++ ++ struct sk_buff_head frags; ++ + unsigned long flags; + + /* keep last! */ diff --git a/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch b/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch new file mode 100644 index 0000000000..ba78f7a142 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/382-mac80211-Switch-to-a-virtual-time-based-airtime-sche.patch @@ -0,0 +1,1277 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Wed, 23 Jun 2021 15:47:55 +0200 +Subject: [PATCH] mac80211: Switch to a virtual time-based airtime scheduler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This switches the airtime scheduler in mac80211 to use a virtual +time-based scheduler instead of the round-robin scheduler used before. +This has a couple of advantages: + +- No need to sync up the round-robin scheduler in firmware/hardware with + the round-robin airtime scheduler. + +- If several stations are eligible for transmission we can schedule both + of them; no need to hard-block the scheduling rotation until the head + of the queue has used up its quantum. + +- The check of whether a station is eligible for transmission becomes + simpler (in ieee80211_txq_may_transmit()). + +The drawback is that scheduling becomes slightly more expensive, as we +need to maintain an rbtree of TXQs sorted by virtual time. This means +that ieee80211_register_airtime() becomes O(logN) in the number of +currently scheduled TXQs because it can change the order of the +scheduled stations. We mitigate this overhead by only resorting when a +station changes position in the tree, and hopefully N rarely grows too +big (it's only TXQs currently backlogged, not all associated stations), +so it shouldn't be too big of an issue. + +To prevent divisions in the fast path, we maintain both station sums and +pre-computed reciprocals of the sums. This turns the fast-path operation +into a multiplication, with divisions only happening as the number of +active stations change (to re-compute the current sum of all active +station weights). To prevent this re-computation of the reciprocal from +happening too frequently, we use a time-based notion of station +activity, instead of updating the weight every time a station gets +scheduled or de-scheduled. As queues can oscillate between empty and +occupied quite frequently, this can significantly cut down on the number +of re-computations. It also has the added benefit of making the station +airtime calculation independent on whether the queue happened to have +drained at the time an airtime value was accounted. + +Co-developed-by: Yibo Zhao +Signed-off-by: Yibo Zhao +Signed-off-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/20210623134755.235545-1-toke@redhat.com +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6552,9 +6552,6 @@ static inline void ieee80211_txq_schedul + { + } + +-void __ieee80211_schedule_txq(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq, bool force); +- + /** + * ieee80211_schedule_txq - schedule a TXQ for transmission + * +@@ -6567,11 +6564,7 @@ void __ieee80211_schedule_txq(struct iee + * The driver may call this function if it has buffered packets for + * this TXQ internally. + */ +-static inline void +-ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) +-{ +- __ieee80211_schedule_txq(hw, txq, true); +-} ++void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); + + /** + * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() +@@ -6583,12 +6576,8 @@ ieee80211_schedule_txq(struct ieee80211_ + * The driver may set force=true if it has buffered packets for this TXQ + * internally. + */ +-static inline void +-ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, +- bool force) +-{ +- __ieee80211_schedule_txq(hw, txq, force); +-} ++void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, ++ bool force); + + /** + * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1442,6 +1442,38 @@ static void sta_apply_mesh_params(struct + #endif + } + ++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) +@@ -1629,7 +1661,8 @@ static int sta_apply_parameters(struct i + sta_apply_mesh_params(local, sta, params); + + if (params->airtime_weight) +- sta->airtime_weight = params->airtime_weight; ++ sta_apply_airtime_params(local, sta, params); ++ + + /* 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->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]); ++ 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); + 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; + +- q_limit_low_old = local->aql_txq_limit_low[ac]; +- q_limit_high_old = local->aql_txq_limit_high[ac]; ++ q_limit_low_old = local->airtime[ac].aql_txq_limit_low; ++ q_limit_high_old = local->airtime[ac].aql_txq_limit_high; + +- local->aql_txq_limit_low[ac] = q_limit_low; +- local->aql_txq_limit_high[ac] = q_limit_high; ++ local->airtime[ac].aql_txq_limit_low = q_limit_low; ++ local->airtime[ac].aql_txq_limit_high = q_limit_high; + + mutex_lock(&local->sta_mtx); + list_for_each_entry(sta, &local->sta_list, list) { +@@ -382,6 +382,46 @@ static const struct file_operations forc + .llseek = default_llseek, + }; + ++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) +@@ -624,7 +664,11 @@ void debugfs_hw_add(struct ieee80211_loc + if (local->ops->wake_tx_queue) + DEBUGFS_ADD_MODE(aqm, 0600); + +- DEBUGFS_ADD_MODE(airtime_flags, 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(aql_txq_limit); + debugfs_create_u32("aql_threshold", 0600, +--- a/net/mac80211/debugfs_netdev.c ++++ b/net/mac80211/debugfs_netdev.c +@@ -513,6 +513,34 @@ static ssize_t ieee80211_if_fmt_aqm( + } + IEEE80211_IF_FILE_R(aqm); + ++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); + + /* IBSS attributes */ +@@ -661,8 +689,10 @@ 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); ++ } + } + + 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; +- s64 deficit[IEEE80211_NUM_ACS]; ++ u64 v_t[IEEE80211_NUM_ACS]; + ssize_t rv; + int ac; + +@@ -210,18 +210,18 @@ static ssize_t sta_airtime_read(struct f + return -ENOMEM; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +- spin_lock_bh(&local->active_txq_lock[ac]); ++ spin_lock_bh(&local->airtime[ac].lock); + rx_airtime += sta->airtime[ac].rx_airtime; + tx_airtime += sta->airtime[ac].tx_airtime; +- deficit[ac] = sta->airtime[ac].deficit; +- spin_unlock_bh(&local->active_txq_lock[ac]); ++ v_t[ac] = sta->airtime[ac].v_t; ++ spin_unlock_bh(&local->airtime[ac].lock); + } + + 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", +- rx_airtime, tx_airtime, sta->airtime_weight, +- deficit[0], deficit[1], deficit[2], deficit[3]); ++ "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]); + + 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->active_txq_lock[ac]); ++ spin_lock_bh(&local->airtime[ac].lock); + sta->airtime[ac].rx_airtime = 0; + sta->airtime[ac].tx_airtime = 0; +- sta->airtime[ac].deficit = sta->airtime_weight; +- spin_unlock_bh(&local->active_txq_lock[ac]); ++ sta->airtime[ac].v_t = 0; ++ spin_unlock_bh(&local->airtime[ac].lock); + } + + return count; +@@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file + return -ENOMEM; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +- spin_lock_bh(&local->active_txq_lock[ac]); ++ spin_lock_bh(&local->airtime[ac].lock); + q_limit_l[ac] = sta->airtime[ac].aql_limit_low; + q_limit_h[ac] = sta->airtime[ac].aql_limit_high; +- spin_unlock_bh(&local->active_txq_lock[ac]); ++ spin_unlock_bh(&local->airtime[ac].lock); + q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending); + } + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -840,20 +840,16 @@ 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 +- * @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 ++ * @frags: used to keep fragments created after dequeue + */ + struct txq_info { + struct fq_tin tin; + struct codel_vars def_cvars; + struct codel_stats cstats; +- +- u16 schedule_round; +- struct list_head schedule_order; ++ struct rb_node schedule_order; + + struct sk_buff_head frags; +- + unsigned long flags; + + /* keep last! */ +@@ -930,6 +926,8 @@ struct ieee80211_sub_if_data { + struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; + struct mac80211_qos_map __rcu *qos_map; + ++ 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; +@@ -1143,6 +1141,44 @@ 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 { +@@ -1156,13 +1192,8 @@ struct ieee80211_local { + struct codel_params cparams; + + /* protects active_txqs and txqi->schedule_order */ +- spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; +- struct list_head active_txqs[IEEE80211_NUM_ACS]; +- u16 schedule_round[IEEE80211_NUM_ACS]; +- ++ struct airtime_sched_info airtime[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; + +@@ -1581,6 +1612,125 @@ static inline bool txq_has_queue(struct + return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets); + } + ++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) + { + return ether_addr_equal(raddr, addr) || +@@ -1821,6 +1971,14 @@ 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 +@@ -2067,6 +2067,9 @@ int ieee80211_if_add(struct ieee80211_lo + } + } + ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) ++ init_airtime_info(&sdata->airtime[i], &local->airtime[i]); ++ + ieee80211_set_default_queues(sdata); + + sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -693,10 +693,13 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + spin_lock_init(&local->queue_stop_reason_lock); + + for (i = 0; i < IEEE80211_NUM_ACS; i++) { +- 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] = ++ 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 = + IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; + } + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1573,12 +1573,8 @@ 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); + +- 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]); ++ ieee80211_unschedule_txq(&local->hw, txq, false); + + 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,15 +426,11 @@ 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]); +- 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]; ++ init_airtime_info(&sta->airtime[i], &local->airtime[i]); + } + + for (i = 0; i < IEEE80211_NUM_TIDS; i++) +@@ -1898,24 +1894,59 @@ void ieee80211_sta_set_buffered(struct i + } + EXPORT_SYMBOL(ieee80211_sta_set_buffered); + +-void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, +- u32 tx_airtime, u32 rx_airtime) ++void ieee80211_register_airtime(struct ieee80211_txq *txq, ++ u32 tx_airtime, u32 rx_airtime) + { +- 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); ++ 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; + u32 airtime = 0; + +- if (sta->local->airtime_flags & AIRTIME_USE_TX) ++ air_sched = &local->airtime[txq->ac]; ++ air_info = to_airtime_info(txq); ++ ++ if (local->airtime_flags & AIRTIME_USE_TX) + airtime += tx_airtime; +- if (sta->local->airtime_flags & AIRTIME_USE_RX) ++ if (local->airtime_flags & AIRTIME_USE_RX) + 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]); ++ /* 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); + } + EXPORT_SYMBOL(ieee80211_sta_register_airtime); + +@@ -2364,7 +2395,7 @@ void sta_set_sinfo(struct sta_info *sta, + } + + if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { +- sinfo->airtime_weight = sta->airtime_weight; ++ sinfo->airtime_weight = sta->airtime[0].weight; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); + } + +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -135,18 +135,25 @@ enum ieee80211_agg_stop_reason { + #define AIRTIME_USE_TX BIT(0) + #define AIRTIME_USE_RX BIT(1) + ++ + struct airtime_info { + u64 rx_airtime; + u64 tx_airtime; +- s64 deficit; ++ u64 v_t; ++ u64 last_scheduled; ++ struct list_head list; + atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ + u32 aql_limit_low; + u32 aql_limit_high; ++ u32 weight_reciprocal; ++ u16 weight; + }; + + 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 sta_info; + +@@ -515,7 +522,6 @@ 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 +@@ -646,7 +652,6 @@ 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 +@@ -972,6 +972,25 @@ 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); ++ } + } + + /* SNMP counters +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1489,7 +1490,7 @@ void ieee80211_txq_init(struct ieee80211 + codel_vars_init(&txqi->def_cvars); + codel_stats_init(&txqi->cstats); + __skb_queue_head_init(&txqi->frags); +- INIT_LIST_HEAD(&txqi->schedule_order); ++ RB_CLEAR_NODE(&txqi->schedule_order); + + txqi->txq.vif = &sdata->vif; + +@@ -1533,9 +1534,7 @@ void ieee80211_txq_purge(struct ieee8021 + ieee80211_purge_tx_queue(&local->hw, &txqi->frags); + spin_unlock_bh(&fq->lock); + +- 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]); ++ ieee80211_unschedule_txq(&local->hw, &txqi->txq, true); + } + + void ieee80211_txq_set_params(struct ieee80211_local *local) +@@ -3797,102 +3796,259 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); + struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct airtime_sched_info *air_sched; ++ u64 now = ktime_get_boottime_ns(); + struct ieee80211_txq *ret = NULL; +- struct txq_info *txqi = NULL, *head = NULL; +- bool found_eligible_txq = false; ++ struct airtime_info *air_info; ++ struct txq_info *txqi = NULL; ++ struct rb_node *node; ++ bool first = false; + +- spin_lock_bh(&local->active_txq_lock[ac]); ++ air_sched = &local->airtime[ac]; ++ spin_lock_bh(&air_sched->lock); + +- begin: +- txqi = list_first_entry_or_null(&local->active_txqs[ac], +- struct txq_info, +- schedule_order); +- if (!txqi) ++ 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; + +- if (txqi == head) { +- if (!found_eligible_txq) +- goto out; +- else +- found_eligible_txq = false; ++ 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))) ++ goto out; ++ ++ if (!ieee80211_txq_airtime_check(hw, &txqi->txq)) { ++ first = false; ++ goto begin; + } + +- if (!head) +- head = txqi; ++ 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); + +- 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; ++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 (aql_check) +- found_eligible_txq = true; ++ if (new_air->v_t <= old_air->v_t) { ++ new = &parent->rb_left; ++ } else { ++ new = &parent->rb_right; ++ leftmost = false; ++ } ++ } + +- 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; ++ 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]; ++ ++ 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; ++ ++ /* 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 ((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 ((!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_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_boottime_ns(); ++ struct airtime_info *air_info; ++ u8 ac = txq->ac; ++ bool was_active; + +- if (txqi->schedule_round == local->schedule_round[ac]) ++ 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)) + goto out; + +- list_del_init(&txqi->schedule_order); +- txqi->schedule_round = local->schedule_round[ac]; +- ret = &txqi->txq; ++ /* 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); + + out: +- spin_unlock_bh(&local->active_txq_lock[ac]); +- return ret; ++ spin_unlock_bh(&air_sched->lock); + } +-EXPORT_SYMBOL(ieee80211_next_txq); ++EXPORT_SYMBOL(ieee80211_schedule_txq); + +-void __ieee80211_schedule_txq(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq, +- bool force) ++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; + +- spin_lock_bh(&local->active_txq_lock[txq->ac]); ++ air_sched = &local->airtime[txq->ac]; ++ air_info = to_airtime_info(&txqi->txq); + +- 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]); ++ lockdep_assert_held(&air_sched->lock); ++ ++ if (purge) { ++ list_del_init(&air_info->list); ++ ieee80211_update_airtime_weight(local, air_sched, 0, true); + } + +- spin_unlock_bh(&local->active_txq_lock[txq->ac]); ++ 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_boottime_ns()); ++ ++ rb_erase_cached(&txqi->schedule_order, ++ &air_sched->active_txqs); ++ RB_CLEAR_NODE(&txqi->schedule_order); ++} ++ ++void ieee80211_unschedule_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) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = to_txq_info(txq); ++ ++ spin_lock_bh(&local->airtime[txq->ac].lock); ++ ++ if (!RB_EMPTY_NODE(&txqi->schedule_order) && !force && ++ !txq_has_queue(txq)) ++ __ieee80211_unschedule_txq(hw, txq, false); ++ ++ spin_unlock_bh(&local->airtime[txq->ac].lock); + } +-EXPORT_SYMBOL(__ieee80211_schedule_txq); ++EXPORT_SYMBOL(ieee80211_return_txq); + + DEFINE_STATIC_KEY_FALSE(aql_disable); + + bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) + { +- struct sta_info *sta; ++ struct airtime_info *air_info = to_airtime_info(txq); + struct ieee80211_local *local = hw_to_local(hw); + + if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) +@@ -3907,15 +4063,12 @@ bool ieee80211_txq_airtime_check(struct + if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) + return true; + +- 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) ++ if (atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_low) + return true; + + if (atomic_read(&local->aql_total_pending_airtime) < + local->aql_threshold && +- atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < +- sta->airtime[txq->ac].aql_limit_high) ++ atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_high) + return true; + + return false; +@@ -3925,60 +4078,59 @@ 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 txq_info *iter, *tmp, *txqi = to_txq_info(txq); +- struct sta_info *sta; +- u8 ac = txq->ac; ++ struct airtime_sched_info *air_sched; ++ struct airtime_info *air_info; ++ struct rb_node *node = NULL; ++ bool ret = false; ++ u64 now; + +- spin_lock_bh(&local->active_txq_lock[ac]); + +- if (!txqi->txq.sta) +- goto out; ++ if (!ieee80211_txq_airtime_check(hw, txq)) ++ return false; ++ ++ air_sched = &local->airtime[txq->ac]; ++ spin_lock_bh(&air_sched->lock); + +- if (list_empty(&txqi->schedule_order)) ++ if (RB_EMPTY_NODE(&txqi->schedule_order)) + goto out; + +- list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], +- schedule_order) { +- if (iter == txqi) +- break; ++ now = ktime_get_boottime_ns(); + +- 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]); ++ /* 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); + } + +- 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]); ++ air_info = to_airtime_info(&txqi->txq); ++ if (air_info->v_t <= air_sched->v_t) { ++ air_sched->last_schedule_activity = now; ++ ret = true; ++ } + +- return false; + out: +- if (!list_empty(&txqi->schedule_order)) +- list_del_init(&txqi->schedule_order); +- spin_unlock_bh(&local->active_txq_lock[ac]); +- +- return true; ++ spin_unlock_bh(&air_sched->lock); ++ return ret; + } + EXPORT_SYMBOL(ieee80211_txq_may_transmit); + + void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct airtime_sched_info *air_sched = &local->airtime[ac]; + +- spin_lock_bh(&local->active_txq_lock[ac]); +- local->schedule_round[ac]++; +- spin_unlock_bh(&local->active_txq_lock[ac]); ++ spin_lock_bh(&air_sched->lock); ++ air_sched->schedule_pos = NULL; ++ spin_unlock_bh(&air_sched->lock); + } + EXPORT_SYMBOL(ieee80211_txq_schedule_start); + diff --git a/package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch b/package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch new file mode 100644 index 0000000000..5a82f00c9e --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/383-mac80211-fix-enabling-4-address-mode-on-a-sta-vif-af.patch @@ -0,0 +1,72 @@ +From: Felix Fietkau +Date: Fri, 2 Jul 2021 06:57:53 +0200 +Subject: [PATCH] mac80211: fix enabling 4-address mode on a sta vif after + assoc + +Notify the driver about the 4-address mode change and also send a nulldata +packet to the AP to notify it about the change + +Fixes: 1ff4e8f2dec8 ("mac80211: notify the driver when a sta uses 4-address mode") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -152,6 +152,8 @@ static int ieee80211_change_iface(struct + struct vif_params *params) + { + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++ struct sta_info *sta; + int ret; + + ret = ieee80211_if_change_type(sdata, type); +@@ -162,7 +164,24 @@ static int ieee80211_change_iface(struct + RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); + ieee80211_check_fast_rx_iface(sdata); + } else if (type == NL80211_IFTYPE_STATION && params->use_4addr >= 0) { ++ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; ++ ++ if (params->use_4addr == ifmgd->use_4addr) ++ return 0; ++ + sdata->u.mgd.use_4addr = params->use_4addr; ++ if (!ifmgd->associated) ++ return 0; ++ ++ mutex_lock(&local->sta_mtx); ++ sta = sta_info_get(sdata, ifmgd->bssid); ++ if (sta) ++ drv_sta_set_4addr(local, sdata, &sta->sta, ++ params->use_4addr); ++ mutex_unlock(&local->sta_mtx); ++ ++ if (params->use_4addr) ++ ieee80211_send_4addr_nullfunc(local, sdata); + } + + if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2224,6 +2224,8 @@ void ieee80211_dynamic_ps_timer(struct t + void ieee80211_send_nullfunc(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + bool powersave); ++void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata); + void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, + struct ieee80211_hdr *hdr, bool ack, u16 tx_time); + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1115,8 +1115,8 @@ void ieee80211_send_nullfunc(struct ieee + ieee80211_tx_skb(sdata, skb); + } + +-static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, +- struct ieee80211_sub_if_data *sdata) ++void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, ++ struct ieee80211_sub_if_data *sdata) + { + struct sk_buff *skb; + struct ieee80211_hdr *nullfunc; diff --git a/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch b/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch new file mode 100644 index 0000000000..0c9ae3595d --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/384-nl80211-add-common-API-to-configure-SAR-power-limita.patch @@ -0,0 +1,398 @@ +From: Carl Huang +Date: Thu, 3 Dec 2020 05:37:26 -0500 +Subject: [PATCH] nl80211: add common API to configure SAR power limitations + +NL80211_CMD_SET_SAR_SPECS is added to configure SAR from +user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR +power specification when used with NL80211_CMD_SET_SAR_SPECS. + +Wireless driver needs to register SAR type, supported frequency +ranges to wiphy, so user space can query it. The index in +frequency range is used to specify which sub band the power +limitation applies to. The SAR type is for compatibility, so later +other SAR mechanism can be implemented without breaking the user +space SAR applications. + +Normal process is user space queries the SAR capability, and +gets the index of supported frequency ranges and associates the +power limitation with this index and sends to kernel. + +Here is an example of message send to kernel: +8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81 +08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80 +08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00 +14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00 +48 00 00 00 + +NL80211_CMD_SET_SAR_SPECS: 0x8c +NL80211_ATTR_WIPHY: 0x01(phy idx is 0) +NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED) +NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER) +NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED) +freq range 0 power: 0x38 in 0.25dbm unit (14dbm) +freq range 1 power: 0x48 in 0.25dbm unit (18dbm) + +Signed-off-by: Carl Huang +Reviewed-by: Brian Norris +Reviewed-by: Abhishek Kumar +Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org +[minor edits, NLA parse cleanups] +Signed-off-by: Johannes Berg +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1737,6 +1737,54 @@ struct station_info { + u8 connected_to_as; + }; + ++/** ++ * struct cfg80211_sar_sub_specs - sub specs limit ++ * @power: power limitation in 0.25dbm ++ * @freq_range_index: index the power limitation applies to ++ */ ++struct cfg80211_sar_sub_specs { ++ s32 power; ++ u32 freq_range_index; ++}; ++ ++/** ++ * struct cfg80211_sar_specs - sar limit specs ++ * @type: it's set with power in 0.25dbm or other types ++ * @num_sub_specs: number of sar sub specs ++ * @sub_specs: memory to hold the sar sub specs ++ */ ++struct cfg80211_sar_specs { ++ enum nl80211_sar_type type; ++ u32 num_sub_specs; ++ struct cfg80211_sar_sub_specs sub_specs[]; ++}; ++ ++ ++/** ++ * @struct cfg80211_sar_chan_ranges - sar frequency ranges ++ * @start_freq: start range edge frequency ++ * @end_freq: end range edge frequency ++ */ ++struct cfg80211_sar_freq_ranges { ++ u32 start_freq; ++ u32 end_freq; ++}; ++ ++/** ++ * struct cfg80211_sar_capa - sar limit capability ++ * @type: it's set via power in 0.25dbm or other types ++ * @num_freq_ranges: number of frequency ranges ++ * @freq_ranges: memory to hold the freq ranges. ++ * ++ * Note: WLAN driver may append new ranges or split an existing ++ * range to small ones and then append them. ++ */ ++struct cfg80211_sar_capa { ++ enum nl80211_sar_type type; ++ u32 num_freq_ranges; ++ const struct cfg80211_sar_freq_ranges *freq_ranges; ++}; ++ + #if IS_ENABLED(CPTCFG_CFG80211) + /** + * cfg80211_get_station - retrieve information about a given station +@@ -4259,6 +4307,8 @@ struct cfg80211_ops { + struct cfg80211_tid_config *tid_conf); + int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev, + const u8 *peer, u8 tids); ++ int (*set_sar_specs)(struct wiphy *wiphy, ++ struct cfg80211_sar_specs *sar); + }; + + /* +@@ -5030,6 +5080,8 @@ struct wiphy { + + u8 max_data_retry_count; + ++ const struct cfg80211_sar_capa *sar_capa; ++ + char priv[] __aligned(NETDEV_ALIGN); + }; + +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL + .len = IEEE80211_MAX_DATA_LEN } + }; + ++static const struct nla_policy ++sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = { ++ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 }, ++ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 }, ++}; ++ ++static const struct nla_policy ++sar_policy[NL80211_SAR_ATTR_MAX + 1] = { ++ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE), ++ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy), ++}; ++ + 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 }, +@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_SAE_PWE] = + NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK, + NL80211_SAE_PWE_BOTH), ++ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), + [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, + }; + +@@ -2117,6 +2130,56 @@ fail: + return -ENOBUFS; + } + ++static int ++nl80211_put_sar_specs(struct cfg80211_registered_device *rdev, ++ struct sk_buff *msg) ++{ ++ struct nlattr *sar_capa, *specs, *sub_freq_range; ++ u8 num_freq_ranges; ++ int i; ++ ++ if (!rdev->wiphy.sar_capa) ++ return 0; ++ ++ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges; ++ ++ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC); ++ if (!sar_capa) ++ return -ENOSPC; ++ ++ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type)) ++ goto fail; ++ ++ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS); ++ if (!specs) ++ goto fail; ++ ++ /* report supported freq_ranges */ ++ for (i = 0; i < num_freq_ranges; i++) { ++ sub_freq_range = nla_nest_start(msg, i + 1); ++ if (!sub_freq_range) ++ goto fail; ++ ++ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ, ++ rdev->wiphy.sar_capa->freq_ranges[i].start_freq)) ++ goto fail; ++ ++ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ, ++ rdev->wiphy.sar_capa->freq_ranges[i].end_freq)) ++ goto fail; ++ ++ nla_nest_end(msg, sub_freq_range); ++ } ++ ++ nla_nest_end(msg, specs); ++ nla_nest_end(msg, sar_capa); ++ ++ return 0; ++fail: ++ nla_nest_cancel(msg, sar_capa); ++ return -ENOBUFS; ++} ++ + struct nl80211_dump_wiphy_state { + s64 filter_wiphy; + long start; +@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg + CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST); + CMD(update_connect_params, UPDATE_CONNECT_PARAMS); + CMD(update_ft_ies, UPDATE_FT_IES); ++ if (rdev->wiphy.sar_capa) ++ CMD(set_sar_specs, SET_SAR_SPECS); + } + #undef CMD + +@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg + + if (nl80211_put_tid_config_support(rdev, msg)) + goto nla_put_failure; ++ state->split_start++; ++ break; ++ case 16: ++ if (nl80211_put_sar_specs(rdev, msg)) ++ goto nla_put_failure; + + /* done */ + state->split_start = 0; +@@ -14713,6 +14783,111 @@ static void nl80211_post_doit(__genl_con + } + } + ++static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev, ++ struct cfg80211_sar_specs *sar_specs, ++ struct nlattr *spec[], int index) ++{ ++ u32 range_index, i; ++ ++ if (!sar_specs || !spec) ++ return -EINVAL; ++ ++ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] || ++ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]) ++ return -EINVAL; ++ ++ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]); ++ ++ /* check if range_index exceeds num_freq_ranges */ ++ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges) ++ return -EINVAL; ++ ++ /* check if range_index duplicates */ ++ for (i = 0; i < index; i++) { ++ if (sar_specs->sub_specs[i].freq_range_index == range_index) ++ return -EINVAL; ++ } ++ ++ sar_specs->sub_specs[index].power = ++ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]); ++ ++ sar_specs->sub_specs[index].freq_range_index = range_index; ++ ++ return 0; ++} ++ ++static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct cfg80211_registered_device *rdev = info->user_ptr[0]; ++ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1]; ++ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1]; ++ struct cfg80211_sar_specs *sar_spec; ++ enum nl80211_sar_type type; ++ struct nlattr *spec_list; ++ u32 specs; ++ int rem, err; ++ ++ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs) ++ return -EOPNOTSUPP; ++ ++ if (!info->attrs[NL80211_ATTR_SAR_SPEC]) ++ return -EINVAL; ++ ++ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX, ++ info->attrs[NL80211_ATTR_SAR_SPEC], ++ NULL, NULL); ++ ++ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS]) ++ return -EINVAL; ++ ++ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]); ++ if (type != rdev->wiphy.sar_capa->type) ++ return -EINVAL; ++ ++ specs = 0; ++ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) ++ specs++; ++ ++ if (specs > rdev->wiphy.sar_capa->num_freq_ranges) ++ return -EINVAL; ++ ++ sar_spec = kzalloc(sizeof(*sar_spec) + ++ specs * sizeof(struct cfg80211_sar_sub_specs), ++ GFP_KERNEL); ++ if (!sar_spec) ++ return -ENOMEM; ++ ++ sar_spec->type = type; ++ specs = 0; ++ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) { ++ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX, ++ spec_list, NULL, NULL); ++ ++ switch (type) { ++ case NL80211_SAR_TYPE_POWER: ++ if (nl80211_set_sar_sub_specs(rdev, sar_spec, ++ spec, specs)) { ++ err = -EINVAL; ++ goto error; ++ } ++ break; ++ default: ++ err = -EINVAL; ++ goto error; ++ } ++ specs++; ++ } ++ ++ sar_spec->num_sub_specs = specs; ++ ++ rdev->cur_cmd_info = info; ++ err = rdev_set_sar_specs(rdev, sar_spec); ++ rdev->cur_cmd_info = NULL; ++error: ++ kfree(sar_spec); ++ return err; ++} ++ + static __genl_const struct genl_ops nl80211_ops[] = { + { + .cmd = NL80211_CMD_GET_WIPHY, +@@ -15576,6 +15751,14 @@ static const struct genl_small_ops nl802 + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, + }, ++ { ++ .cmd = NL80211_CMD_SET_SAR_SPECS, ++ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, ++ .doit = nl80211_set_sar_specs, ++ .flags = GENL_UNS_ADMIN_PERM, ++ .internal_flags = NL80211_FLAG_NEED_WIPHY | ++ NL80211_FLAG_NEED_RTNL, ++ }, + }; + + static struct genl_family nl80211_fam __genl_ro_after_init = { +--- a/net/wireless/rdev-ops.h ++++ b/net/wireless/rdev-ops.h +@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config( + return ret; + } + ++static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev, ++ struct cfg80211_sar_specs *sar) ++{ ++ int ret; ++ ++ trace_rdev_set_sar_specs(&rdev->wiphy, sar); ++ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar); ++ trace_rdev_return_int(&rdev->wiphy, ret); ++ ++ return ret; ++} ++ + #endif /* __CFG80211_RDEV_OPS */ +--- a/net/wireless/trace.h ++++ b/net/wireless/trace.h +@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config, + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x", + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids) + ); ++ ++TRACE_EVENT(rdev_set_sar_specs, ++ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar), ++ TP_ARGS(wiphy, sar), ++ TP_STRUCT__entry( ++ WIPHY_ENTRY ++ __field(u16, type) ++ __field(u16, num) ++ ), ++ TP_fast_assign( ++ WIPHY_ASSIGN; ++ __entry->type = sar->type; ++ __entry->num = sar->num_sub_specs; ++ ++ ), ++ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d", ++ WIPHY_PR_ARG, __entry->type, __entry->num) ++); ++ + #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ + + #undef TRACE_INCLUDE_PATH diff --git a/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch b/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch new file mode 100644 index 0000000000..c351bc812a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/385-mac80211-add-ieee80211_set_sar_specs.patch @@ -0,0 +1,51 @@ +From: Carl Huang +Date: Thu, 3 Dec 2020 05:37:27 -0500 +Subject: [PATCH] mac80211: add ieee80211_set_sar_specs + +This change registers ieee80211_set_sar_specs to +mac80211_config_ops, so cfg80211 can call it. + +Signed-off-by: Carl Huang +Reviewed-by: Brian Norris +Reviewed-by: Abhishek Kumar +Link: https://lore.kernel.org/r/20201203103728.3034-3-cjhuang@codeaurora.org +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -4207,6 +4207,8 @@ struct ieee80211_ops { + struct ieee80211_vif *vif); + void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool enabled); ++ int (*set_sar_specs)(struct ieee80211_hw *hw, ++ const struct cfg80211_sar_specs *sar); + void (*sta_set_decap_offload)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, bool enabled); +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4136,6 +4136,17 @@ static int ieee80211_reset_tid_config(st + return ret; + } + ++static int ieee80211_set_sar_specs(struct wiphy *wiphy, ++ struct cfg80211_sar_specs *sar) ++{ ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ ++ if (!local->ops->set_sar_specs) ++ return -EOPNOTSUPP; ++ ++ return local->ops->set_sar_specs(&local->hw, sar); ++} ++ + const struct cfg80211_ops mac80211_config_ops = { + .add_virtual_intf = ieee80211_add_iface, + .del_virtual_intf = ieee80211_del_iface, +@@ -4239,4 +4250,5 @@ const struct cfg80211_ops mac80211_confi + .probe_mesh_link = ieee80211_probe_mesh_link, + .set_tid_config = ieee80211_set_tid_config, + .reset_tid_config = ieee80211_reset_tid_config, ++ .set_sar_specs = ieee80211_set_sar_specs, + }; 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 3d1bb3d6c8..b2ee61a6dc 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,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -3736,6 +3736,7 @@ struct mgmt_frame_regs { +@@ -3793,6 +3793,7 @@ struct mgmt_frame_regs { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -8,7 +8,7 @@ * * @set_wds_peer: set the WDS peer for a WDS interface * -@@ -4058,6 +4059,7 @@ struct cfg80211_ops { +@@ -4115,6 +4116,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -36,7 +36,7 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -2531,6 +2531,9 @@ enum nl80211_commands { +@@ -2560,6 +2560,9 @@ enum nl80211_commands { * disassoc events to indicate that an immediate reconnect to the AP * is desired. * @@ -46,9 +46,9 @@ * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3022,6 +3025,8 @@ enum nl80211_attrs { +@@ -3057,6 +3060,8 @@ enum nl80211_attrs { - NL80211_ATTR_RECONNECT_REQUESTED, + NL80211_ATTR_DISABLE_HE, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2707,6 +2707,19 @@ static int ieee80211_get_tx_power(struct +@@ -2761,6 +2761,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, const u8 *addr) { -@@ -4137,6 +4150,7 @@ const struct cfg80211_ops mac80211_confi +@@ -4202,6 +4215,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, @@ -87,7 +87,7 @@ CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1403,6 +1403,7 @@ struct ieee80211_local { +@@ -1426,6 +1426,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ @@ -129,15 +129,15 @@ local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -733,6 +733,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_S1G_CAPABILITY_MASK] = - NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN), +@@ -753,6 +753,7 @@ static const struct nla_policy nl80211_p + NL80211_SAE_PWE_BOTH), + [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy), [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT }, + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -3241,6 +3242,20 @@ static int nl80211_set_wiphy(struct sk_b +@@ -3318,6 +3319,20 @@ static int nl80211_set_wiphy(struct sk_b if (result) return result; } -- 2.25.1