diff --git a/package/kernel/ath10k-ct/patches/999-001-fix-ath10k_update_vif_offload.patch b/package/kernel/ath10k-ct/patches/999-001-fix-ath10k_update_vif_offload.patch new file mode 100644 index 0000000000..2ef718625f --- /dev/null +++ b/package/kernel/ath10k-ct/patches/999-001-fix-ath10k_update_vif_offload.patch @@ -0,0 +1,32 @@ +--- a/ath10k-6.4/mac.c ++++ b/ath10k-6.4/mac.c +@@ -6362,13 +6362,13 @@ + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set txbf conf, value: 0x%x\n", + value); + return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + ar->wmi.vdev_param->txbf, value); + } + +-static void ath10k_update_vif_offload(struct ieee80211_hw *hw, ++static int ath10k_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { + struct ath10k_vif *arvif = (void *)vif->drv_priv; + struct ath10k *ar = hw->priv; + u32 vdev_param; + int ret; +@@ -6384,14 +6384,16 @@ + ATH10K_HW_TXRX_NATIVE_WIFI); + /* 10.X firmware does not support this VDEV parameter. Do not warn */ + if (ret && ret != -EOPNOTSUPP) { + ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", + arvif->vdev_id, ret); + } ++ ++ return ret; + } + + /* + * TODO: + * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE, + * because we will send mgmt frames without CCK. This requirement diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 9e6ad6d88a..dff1ff08ea 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -40,12 +40,14 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_MAC80211_NSS_REDIRECT \ CONFIG_PACKAGE_IWLWIFI_DEBUG \ CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ - CONFIG_PACKAGE_RTLWIFI_DEBUG \ + CONFIG_PACKAGE_RTLWIFI_DEBUG include $(INCLUDE_DIR)/package.mk WMENU:=Wireless Drivers +NSS_PATCH:= subsys ath10k ath11k + define KernelPackage/mac80211/Default SUBMENU:=$(WMENU) URL:=https://wireless.wiki.kernel.org/ @@ -377,7 +379,11 @@ define Build/Patch $(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)/ath12k,ath12k/) - $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) +ifdef CONFIG_ATH11K_NSS_SUPPORT + $(foreach driver,$(NSS_PATCH), + $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/nss/$(driver),nss/$(driver)/) + ) +endif $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mt7601u,mt7601u/) $(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) @@ -395,7 +401,11 @@ define Quilt/Refresh/Package $(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)/ath12k,ath12k/) - $(if $(CONFIG_ATH11K_NSS_SUPPORT),$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath11k_nss,ath11k_nss/)) +ifdef CONFIG_ATH11K_NSS_SUPPORT + $(foreach driver,$(NSS_PATCH), + $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/nss/$(driver),nss/$(driver)/) + ) +endif $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mt7601u,mt7601u/) $(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/) @@ -422,6 +432,13 @@ define Build/InstallDev rm -f $(1)/usr/include/mac80211-backport/linux/module.h endef +ifdef CONFIG_ATH11K_NSS_SUPPORT +define KernelPackage/ath11k/install + $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config + $(INSTALL_BIN) ./files/qca-nss-pbuf.init $(1)/etc/init.d/qca-nss-pbuf + $(INSTALL_BIN) ./files/pbuf.uci $(1)/etc/config/pbuf +endef +endif $(eval $(foreach drv,$(PKG_DRIVERS),$(call KernelPackage,$(drv)))) $(eval $(call KernelPackage,cfg80211)) diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index f8279d833b..a757d685f1 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -13,11 +13,14 @@ PKG_CONFIG_DEPENDS += \ CONFIG_ATH10K_LEDS \ CONFIG_ATH10K_THERMAL \ CONFIG_ATH11K_THERMAL \ + CONFIG_ATH11K_DEBUGFS_STA \ + CONFIG_ATH11K_DEBUGFS_HTT_STATS \ CONFIG_ATH_USER_REGD \ CONFIG_ATH11K_MEM_PROFILE_1G \ CONFIG_ATH11K_MEM_PROFILE_512M \ CONFIG_ATH11K_MEM_PROFILE_256M \ - CONFIG_ATH11K_NSS_SUPPORT + CONFIG_ATH11K_NSS_SUPPORT \ + CONFIG_ATH11K_NSS_MESH_SUPPORT ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS config-y += \ @@ -67,6 +70,9 @@ config-$(CONFIG_ATH11K_MEM_PROFILE_1G) += ATH11K_MEM_PROFILE_1G config-$(CONFIG_ATH11K_MEM_PROFILE_512M) += ATH11K_MEM_PROFILE_512M config-$(CONFIG_ATH11K_MEM_PROFILE_256M) += ATH11K_MEM_PROFILE_256M config-$(CONFIG_ATH11K_NSS_SUPPORT) += ATH11K_NSS_SUPPORT +config-$(CONFIG_ATH11K_NSS_MESH_SUPPORT) += ATH11K_NSS_MESH_SUPPORT +config-$(CONFIG_ATH11K_DEBUGFS_STA) += ATH11K_DEBUGFS_STA +config-$(CONFIG_ATH11K_DEBUGFS_HTT_STATS) += ATH11K_DEBUGFS_HTT_STATS config-$(call config_package,ath9k-htc) += ATH9K_HTC config-$(call config_package,ath10k,regular) += ATH10K ATH10K_PCI @@ -318,7 +324,10 @@ define KernelPackage/ath11k URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k DEPENDS+= +kmod-ath +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT \ +kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal \ - +ATH11K_NSS_SUPPORT:kmod-qca-nss-drv + +ATH11K_NSS_SUPPORT:kmod-qca-nss-drv \ + +ATH11K_NSS_MESH_SUPPORT:kmod-qca-nss-drv-wifi-meshmgr \ + +@(ATH11K_NSS_SUPPORT):NSS_DRV_WIFIOFFLOAD_ENABLE \ + +@(ATH11K_NSS_SUPPORT):NSS_DRV_WIFI_EXT_VDEV_ENABLE FILES:=$(PKG_BUILD_DIR)/drivers/soc/qcom/qmi_helpers.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko ifdef CONFIG_ATH11K_NSS_SUPPORT @@ -332,6 +341,10 @@ This module adds support for Qualcomm Technologies 802.11ax family of chipsets. endef +define KernelPackage/ath11k/conffiles +/etc/config/pbuf +endef + define KernelPackage/ath11k/config config ATH11K_THERMAL @@ -339,6 +352,22 @@ define KernelPackage/ath11k/config depends on PACKAGE_kmod-ath11k default y if TARGET_qualcommax + config ATH11K_DEBUGFS_STA + bool "Enable ath11k station statistics" + depends on PACKAGE_kmod-ath11k + depends on PACKAGE_MAC80211_DEBUGFS + default y + help + Say Y to enable access to the station statistics via debugfs. + + config ATH11K_DEBUGFS_HTT_STATS + bool "Enable ath11k HTT statistics" + depends on PACKAGE_kmod-ath11k + depends on PACKAGE_MAC80211_DEBUGFS + default y + help + Say Y to enable access to the HTT statistics via debugfs. + config ATH11K_NSS_SUPPORT bool "Enable NSS WiFi offload" select ATH11K_MEM_PROFILE_512M if (TARGET_qualcommax_ipq807x_DEVICE_edimax_cax1800 || \ @@ -347,13 +376,17 @@ define KernelPackage/ath11k/config TARGET_qualcommax_ipq807x_DEVICE_redmi_ax6 || \ TARGET_qualcommax_ipq807x_DEVICE_xiaomi_ax3600 || \ TARGET_qualcommax_ipq807x_DEVICE_zte_mf269 ) - select ATH11K_MEM_PROFILE_256M if (TARGET_qualcommax_ipq807x_DEVICE_netgear_wax218) - select NSS_DRV_WIFI_ENABLE - select NSS_DRV_WIFI_EXT_VDEV_ENABLE - default y if TARGET_qualcommax + select ATH11K_MEM_PROFILE_256M if TARGET_qualcommax_ipq807x_DEVICE_netgear_wax218 + + config ATH11K_NSS_MESH_SUPPORT + bool "Enable NSS WiFi Mesh offload" + depends on ATH11K_NSS_SUPPORT + select PACKAGE_MAC80211_MESH + default n choice - prompt "ATH11K Memory Profile" + prompt "Memory Profile" + depends on PACKAGE_kmod-ath11k default ATH11K_MEM_PROFILE_1G help This option allows you to select the memory profile. diff --git a/package/kernel/mac80211/files/pbuf.uci b/package/kernel/mac80211/files/pbuf.uci index 2b277e11f0..4e01048e9b 100644 --- a/package/kernel/mac80211/files/pbuf.uci +++ b/package/kernel/mac80211/files/pbuf.uci @@ -1,6 +1,6 @@ config general opt - option memory_profile 'off' - # option memory_profile 'auto' + # option memory_profile 'off' + option memory_profile 'auto' # option memory_profile '1gb' # option memory_profile '512mb' # option memory_profile '256mb' diff --git a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf b/package/kernel/mac80211/files/qca-nss-pbuf.init similarity index 64% rename from package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf rename to package/kernel/mac80211/files/qca-nss-pbuf.init index 02afd5f6c3..c6d6b8b223 100755 --- a/package/kernel/mac80211/files/etc/init.d/qca-nss-pbuf +++ b/package/kernel/mac80211/files/qca-nss-pbuf.init @@ -17,31 +17,52 @@ START=71 apply_sysctl() { - [ $(sysctl -n -e dev.nss.general.redirect) -eq 0 ] && /etc/init.d/qca-nss-ecm start + [ "$(sysctl -n -e dev.nss.general.redirect)" -eq 0 ] && /etc/init.d/qca-nss-ecm start # Running this script multiple times is useless, as extra_pbuf_core0 # can't be changed if it is allocated, assume it's already been run. - if [ $(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0) -eq 0 ]; then + if [ "$(sysctl -n -e dev.nss.n2hcfg.extra_pbuf_core0)" -eq 0 ]; then logger -t ath11k_nss "$board - setting dev.nss.n2hcfg.extra_pbuf_core0=$extra_pbuf_core0" - sysctl -w dev.nss.n2hcfg.extra_pbuf_core0=$extra_pbuf_core0 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.extra_pbuf_core0="$extra_pbuf_core0" > /dev/null 2> /dev/null else - logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '"$extra_pbuf_core0"'. Skipping applying wifi nss configs" + logger -t ath11k_nss "Sysctl key 'extra_pbuf_core0' already set to '""$extra_pbuf_core0""'. Skipping applying wifi nss configs" fi - sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=$n2h_high_water_core0 > /dev/null 2>/dev/null + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0="$n2h_high_water_core0" > /dev/null 2>/dev/null logger -t ath11k_nss "$board - setting dev.nss.n2hcfg.n2h_wifi_pool_buf=$n2h_wifi_pool_buf" - sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf=$n2h_wifi_pool_buf + sysctl -w dev.nss.n2hcfg.n2h_wifi_pool_buf="$n2h_wifi_pool_buf" logger -t ath11k_nss "$board - setting dev.nss.n2hcfg.n2h_high_water_core0=$n2h_high_water_core0" - sysctl -w dev.nss.n2hcfg.n2h_high_water_core0=$n2h_high_water_core0 + sysctl -w dev.nss.n2hcfg.n2h_high_water_core0="$n2h_high_water_core0" } apply_nss_config() { + if [ ! -r /sys/module/ath11k/parameters/nss_offload ]; then + logger -t ath11k_nss "Module parameter '/sys/module/ath11k/parameters/nss_offload' does NOT exist. Skipping applying wifi nss configs" + exit 1 + fi - sysctl -w dev.nss.n2hcfg.n2h_queue_limit_core0=256 > /dev/null 2> /dev/null - sysctl -w dev.nss.n2hcfg.n2h_queue_limit_core1=256 > /dev/null 2> /dev/null + enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) + + if [ "$enable_nss_offload" -ne "1" ]; then + logger -t ath11k_nss -s user.warn "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" + exit 1 + fi + + [ ! -d "/proc/sys/dev/nss/rps" ] && { + logger -s -t ath11k_nss -p user.error "NSS driver not loaded or disabled! Exiting... " + exit 1 + } + + # Lock NSS clock to highest setting + sysctl -w dev.nss.clock.auto_scale=0 > /dev/null 2> /dev/null + + sysctl -w dev.nss.n2hcfg.n2h_queue_limit_core0=2048 > /dev/null 2> /dev/null + sysctl -w dev.nss.n2hcfg.n2h_queue_limit_core1=2048 > /dev/null 2> /dev/null + + sysctl -w dev.nss.rps.hash_bitmap=15 > /dev/null 2> /dev/null local memory_profile if memory_profile=$(uci_get pbuf.opt.memory_profile); then @@ -64,7 +85,7 @@ apply_nss_config() { ;; esac else - exi 0 + exit 0 fi case "$board" in @@ -84,7 +105,7 @@ apply_nss_config() { yuncore,ax880 | \ zyxel,nbg7815 | \ 1g*) - extra_pbuf_core0=9000000 n2h_high_water_core0=67392 n2h_wifi_pool_buf=40960 apply_sysctl + extra_pbuf_core0=10000000 n2h_high_water_core0=72512 n2h_wifi_pool_buf=36864 apply_sysctl ;; # 512MB profile edimax,cax1800 | \ @@ -94,28 +115,35 @@ apply_nss_config() { xiaomi,ax3600 | \ zte,mf269 | \ 512m*) - extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl + extra_pbuf_core0=3100000 n2h_high_water_core0=30624 n2h_wifi_pool_buf=8192 apply_sysctl ;; # 256MB profile netgear,wax218 | \ 256m*) - extra_pbuf_core0=3100000 n2h_high_water_core0=30258 n2h_wifi_pool_buf=4096 apply_sysctl + extra_pbuf_core0=3100000 n2h_high_water_core0=30258 n2h_wifi_pool_buf=4096 apply_sysctl ;; esac } -start() { - if [ ! -r /sys/module/ath11k/parameters/nss_offload ]; then - logger -t ath11k_nss "Module parameter '/sys/module/ath11k/parameters/nss_offload' does NOT exist. Skipping applying wifi nss configs" - exit 1 - fi +boost_performance() { - enable_nss_offload=$(cat /sys/module/ath11k/parameters/nss_offload) + find /sys/kernel/debug/ath11k -name stats_disable| while read -r stats_disable; do + echo 1 > "$stats_disable" + done - if [ "$enable_nss_offload" = "0" ]; then - logger -t ath11k_nss -s user.warn "Module parameter 'nss_offload=0'. Skipping applying wifi nss configs" - exit 1 - fi + ubus call iwinfo devices | jsonfilter -e "@.devices[*]"| while read -r device; do + tc qdisc replace dev "${device}" root noqueue + done + + for num in 0 1 2 3; do + echo "performance" > /sys/devices/system/cpu/cpu${num}/cpufreq/scaling_governor + done + +} + +start() { + + boost_performance + apply_nss_config - apply_nss_config } diff --git a/package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch b/package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch deleted file mode 100644 index 1826e64bbc..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/107-ath11k-tid-counter-fix.patch +++ /dev/null @@ -1,21 +0,0 @@ -From e227e5896dc8fe69d63334819c5fbada9caddc50 Mon Sep 17 00:00:00 2001 -From: Miles Hu -Date: Tue, 14 Jan 2020 14:29:53 -0800 -Subject: [PATCH] tid fix - ---- - drivers/net/wireless/ath/ath11k/hal_rx.c | 2 +- - drivers/net/wireless/ath/ath11k/hal_rx.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/hal_rx.c -+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c -@@ -905,7 +905,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc - __le32_to_cpu(eu_stats->info1)); - ppdu_info->tid = - ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP, -- __le32_to_cpu(eu_stats->info7))) - 1; -+ __le32_to_cpu(eu_stats->rsvd2[0]))) - 1; - ppdu_info->tcp_msdu_count = - FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT, - __le32_to_cpu(eu_stats->info4)); diff --git a/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch b/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch deleted file mode 100644 index ddae9fcbc5..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/211-ath11k-add-obss-pd-support.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 81694575884dc69535252a6f44128323fd6a2504 Mon Sep 17 00:00:00 2001 -From: Rajkumar Manoharan -Date: Sat, 26 Sep 2020 23:17:03 -0700 -Subject: [PATCH 1/3] nl80211: fix OBSS PD min and max offset validation - -The SRG minimum and maximum offset doesn't present when the SR control field -of Spatial Reuse Parameter Set element set SRG Information Present to 0. -Both attributes are 1-byte values so use appropriate nla_get function. - -Signed-off-by: Rajkumar Manoharan ---- - net/wireless/nl80211.c | 21 ++++++++++----------- - 1 file changed, 10 insertions(+), 11 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3272,7 +3272,8 @@ static int ath11k_mac_config_obss_pd(str - { - u32 bitmap[2], param_id, param_val, pdev_id; - int ret; -- s8 non_srg_th = 0, srg_th = 0; -+ s8 non_srg_th = ATH11K_OBSS_PD_THRESHOLD_DISABLED; -+ s8 srg_th = 0; - - pdev_id = ar->pdev->pdev_id; - -@@ -3301,8 +3302,6 @@ static int ath11k_mac_config_obss_pd(str - if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) - non_srg_th = (ATH11K_OBSS_PD_MAX_THRESHOLD + - he_obss_pd->non_srg_max_offset); -- else -- non_srg_th = ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD; - - param_val |= ATH11K_OBSS_PD_NON_SRG_EN; - } -@@ -3317,7 +3316,8 @@ static int ath11k_mac_config_obss_pd(str - param_val |= ATH11K_OBSS_PD_THRESHOLD_IN_DBM; - param_val |= FIELD_PREP(GENMASK(15, 8), srg_th); - } else { -- non_srg_th -= ATH11K_DEFAULT_NOISE_FLOOR; -+ if ((non_srg_th & 0xff) != ATH11K_OBSS_PD_THRESHOLD_DISABLED) -+ non_srg_th -= ATH11K_DEFAULT_NOISE_FLOOR; - /* SRG not supported and threshold in dB */ - param_val &= ~(ATH11K_OBSS_PD_SRG_EN | - ATH11K_OBSS_PD_THRESHOLD_IN_DBM); ---- a/drivers/net/wireless/ath/ath11k/mac.h -+++ b/drivers/net/wireless/ath/ath11k/mac.h -@@ -121,7 +121,7 @@ struct ath11k_generic_iter { - #define ATH11K_PEER_RX_NSS_80_80MHZ GENMASK(5, 3) - - #define ATH11K_OBSS_PD_MAX_THRESHOLD -82 --#define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62 -+#define ATH11K_OBSS_PD_THRESHOLD_DISABLED 128 - #define ATH11K_OBSS_PD_THRESHOLD_IN_DBM BIT(29) - #define ATH11K_OBSS_PD_SRG_EN BIT(30) - #define ATH11K_OBSS_PD_NON_SRG_EN BIT(31) diff --git a/package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch deleted file mode 100644 index 08e158a407..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/234-001-ath11k-account-tx-rx-packets-flow.patch +++ /dev/null @@ -1,494 +0,0 @@ -From d6d86c0c48c8d114e94c5b5f749c97d629d727ef Mon Sep 17 00:00:00 2001 -From: Maharaja Kennadyrajan -Date: Mon, 4 Jan 2021 23:49:21 +0530 -Subject: [PATCH 1/2] ath11k/mac80211: Add support to account Tx and Rx flow - packets - -Added support to log the inflow and outflow of the Tx and Rx -packets in netif and host driver. - -Command to dump the Tx pkts flow in driver: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/driver_tx_pkts_flow - -Command to dump the Rx pkts flow in driver: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/driver_rx_pkts_flow - -Commands to reset the Tx/Rx pkts flow in driver: -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_tx_stats - -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_rx_stats - -Command to dump the Tx pkts flow in mac80211: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/mac80211_tx_pkts_flow - -Command to dump the Rx pkts flow in mac80211: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/mac80211_rx_pkts_flow - -Commands to reset the Tx/Rx pkts flow in mac80211: -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_mac80211_tx_pkts_flow - -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_mac80211_rx_pkts_flow - -Sample output after running the Tx and Rx traffic. - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/driver_tx_pkts_flow -Tx packets inflow from mac80211: 20 -Tx packets outflow to HW: 20 - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/mac80211_tx_pkts_flow -Tx packets outflow from netif: 20 -Tx packets inflow in mac80211: 20 - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/driver_rx_pkts_flow -Rx packets inflow from HW: 28 -Rx packets outflow from driver: 28 - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/mac80211_rx_pkts_flow -Rx packets inflow in mac80211: 28 -Rx packets inflow in netif: 26 -Rx forwarded packets in bridge: 2 - -Signed-off-by: Maharaja Kennadyrajan ---- - drivers/net/wireless/ath/ath11k/core.h | 12 ++ - drivers/net/wireless/ath/ath11k/debugfs.h | 2 + - drivers/net/wireless/ath/ath11k/debugfs_sta.c | 145 +++++++++++++++++- - drivers/net/wireless/ath/ath11k/dp_rx.c | 38 +++++ - drivers/net/wireless/ath/ath11k/mac.c | 11 ++ - 5 files changed, 207 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -494,6 +494,17 @@ struct ath11k_per_ppdu_tx_stats { - - DECLARE_EWMA(avg_rssi, 10, 8) - -+struct ath11k_driver_tx_pkts_flow { -+ atomic_t pkts_in; -+ atomic_t pkts_out; -+}; -+ -+struct ath11k_driver_rx_pkts_flow { -+ atomic_t pkts_frm_hw; -+ atomic_t pkts_out; -+ atomic_t pkts_out_to_netif; -+}; -+ - struct ath11k_sta { - struct ath11k_vif *arvif; - -@@ -527,6 +538,8 @@ struct ath11k_sta { - #ifdef CPTCFG_ATH11K_NSS_SUPPORT - struct ath11k_nss_sta_stats *nss_stats; - #endif -+ struct ath11k_driver_tx_pkts_flow drv_tx_pkts; -+ struct ath11k_driver_rx_pkts_flow drv_rx_pkts; - u16 tcl_metadata; - - /* Protected with ar->data_lock */ ---- a/drivers/net/wireless/ath/ath11k/debugfs.h -+++ b/drivers/net/wireless/ath/ath11k/debugfs.h -@@ -98,7 +98,7 @@ struct ath_pktlog_hdr { - }; - - #define ATH11K_HTT_PEER_STATS_RESET BIT(16) -- -+#define ATH11K_DRV_TX_STATS_SIZE 1024 - #define ATH11K_HTT_STATS_BUF_SIZE (1024 * 512) - #define ATH11K_FW_STATS_BUF_SIZE (1024 * 1024) - ---- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c -@@ -146,9 +146,6 @@ static ssize_t ath11k_dbg_sta_dump_tx_st - const int size = 2 * 4096; - char *buf; - -- if (!arsta->tx_stats) -- return -ENOENT; -- - buf = kzalloc(size, GFP_KERNEL); - if (!buf) - return -ENOMEM; -@@ -156,6 +153,12 @@ static ssize_t ath11k_dbg_sta_dump_tx_st - mutex_lock(&ar->conf_mutex); - - spin_lock_bh(&ar->data_lock); -+ -+ if (!arsta->tx_stats) { -+ retval = -ENOENT; -+ goto end; -+ } -+ - for (k = 0; k < ATH11K_STATS_TYPE_MAX; k++) { - for (j = 0; j < ATH11K_COUNTER_TYPE_MAX; j++) { - stats = &arsta->tx_stats->stats[k]; -@@ -229,6 +232,11 @@ static ssize_t ath11k_dbg_sta_dump_tx_st - - mutex_unlock(&ar->conf_mutex); - return retval; -+end: -+ spin_unlock_bh(&ar->data_lock); -+ mutex_unlock(&ar->conf_mutex); -+ kfree(buf); -+ return retval; - } - - static const struct file_operations fops_tx_stats = { -@@ -847,17 +855,211 @@ static const struct file_operations fops - .llseek = default_llseek, - }; - -+static ssize_t ath11k_dbg_sta_reset_rx_stats(struct file *file, -+ const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ieee80211_sta *sta = file->private_data; -+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; -+ struct ath11k *ar = arsta->arvif->ar; -+ int ret, reset; -+ -+ if (!arsta->rx_stats) -+ return -ENOENT; -+ -+ ret = kstrtoint_from_user(buf, count, 0, &reset); -+ if (ret) -+ return ret; -+ -+ if (!reset || reset > 1) -+ return -EINVAL; -+ -+ spin_lock_bh(&ar->ab->base_lock); -+ memset(arsta->rx_stats, 0, sizeof(*arsta->rx_stats)); -+ atomic_set(&arsta->drv_rx_pkts.pkts_frm_hw, 0); -+ atomic_set(&arsta->drv_rx_pkts.pkts_out, 0); -+ atomic_set(&arsta->drv_rx_pkts.pkts_out_to_netif, 0); -+ spin_unlock_bh(&ar->ab->base_lock); -+ -+ ret = count; -+ return ret; -+} -+ -+static const struct file_operations fops_reset_rx_stats = { -+ .write = ath11k_dbg_sta_reset_rx_stats, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; -+ -+static ssize_t -+ath11k_dbg_sta_dump_driver_tx_pkts_flow(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ieee80211_sta *sta = file->private_data; -+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; -+ struct ath11k *ar = arsta->arvif->ar; -+ int len = 0, ret_val; -+ const int size = ATH11K_DRV_TX_STATS_SIZE; -+ char *buf; -+ -+ buf = kzalloc(ATH11K_DRV_TX_STATS_SIZE, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ mutex_lock(&ar->conf_mutex); -+ spin_lock_bh(&ar->ab->base_lock); -+ -+ if (!arsta->tx_stats) { -+ ret_val = -ENOENT; -+ goto end; -+ } -+ -+ len += scnprintf(buf + len, size - len, -+ "Tx packets inflow from mac80211: %u\n", -+ atomic_read(&arsta->drv_tx_pkts.pkts_in)); -+ len += scnprintf(buf + len, size - len, -+ "Tx packets outflow to HW: %u\n", -+ atomic_read(&arsta->drv_tx_pkts.pkts_out)); -+ spin_unlock_bh(&ar->ab->base_lock); -+ -+ if (len > size) -+ len = size; -+ -+ ret_val = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ kfree(buf); -+ -+ mutex_unlock(&ar->conf_mutex); -+ return ret_val; -+end: -+ spin_unlock_bh(&ar->ab->base_lock); -+ mutex_unlock(&ar->conf_mutex); -+ kfree(buf); -+ return ret_val; -+} -+ -+static const struct file_operations fops_driver_tx_pkts_flow = { -+ .read = ath11k_dbg_sta_dump_driver_tx_pkts_flow, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; -+ -+static ssize_t ath11k_dbg_sta_reset_tx_stats(struct file *file, -+ const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ieee80211_sta *sta = file->private_data; -+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; -+ struct ath11k *ar = arsta->arvif->ar; -+ int ret, reset; -+ -+ ret = kstrtoint_from_user(buf, count, 0, &reset); -+ if (ret) -+ return ret; -+ -+ if (!reset || reset > 1) -+ return -EINVAL; -+ -+ spin_lock_bh(&ar->ab->base_lock); -+ -+ if (!arsta->tx_stats) { -+ spin_unlock_bh(&ar->ab->base_lock); -+ return -ENOENT; -+ } -+ -+ memset(arsta->tx_stats, 0, sizeof(*arsta->tx_stats)); -+ atomic_set(&arsta->drv_tx_pkts.pkts_in, 0); -+ atomic_set(&arsta->drv_tx_pkts.pkts_out, 0); -+ spin_unlock_bh(&ar->ab->base_lock); -+ -+ ret = count; -+ return ret; -+} -+ -+static const struct file_operations fops_reset_tx_stats = { -+ .write = ath11k_dbg_sta_reset_tx_stats, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; -+ -+static ssize_t -+ath11k_dbg_sta_dump_driver_rx_pkts_flow(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ieee80211_sta *sta = file->private_data; -+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; -+ struct ath11k *ar = arsta->arvif->ar; -+ struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; -+ int len = 0, ret_val = 0; -+ const int size = 1024; -+ char *buf; -+ -+ if (!rx_stats) -+ return -ENOENT; -+ -+ buf = kzalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ mutex_lock(&ar->conf_mutex); -+ spin_lock_bh(&ar->ab->base_lock); -+ -+ len += scnprintf(buf + len, size - len, -+ "Rx packets inflow from HW: %u\n", -+ atomic_read(&arsta->drv_rx_pkts.pkts_frm_hw)); -+ len += scnprintf(buf + len, size - len, -+ "Rx packets outflow from driver: %u\n", -+ atomic_read(&arsta->drv_rx_pkts.pkts_out)); -+ len += scnprintf(buf + len, size - len, -+ "Rx packets outflow from driver to netif in Fast rx: %u\n", -+ atomic_read(&arsta->drv_rx_pkts.pkts_out_to_netif)); -+ -+ len += scnprintf(buf + len, size - len, "\n"); -+ -+ spin_unlock_bh(&ar->ab->base_lock); -+ -+ if (len > size) -+ len = size; -+ -+ ret_val = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ kfree(buf); -+ -+ mutex_unlock(&ar->conf_mutex); -+ return ret_val; -+} -+ -+static const struct file_operations fops_driver_rx_pkts_flow = { -+ .read = ath11k_dbg_sta_dump_driver_rx_pkts_flow, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; -+ - void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, struct dentry *dir) - { - struct ath11k *ar = hw->priv; - -- if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) -- debugfs_create_file("tx_stats", 0400, dir, sta, -- &fops_tx_stats); -- if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) -+ if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) { -+ debugfs_create_file("tx_stats", 0400, dir, sta, -+ &fops_tx_stats); -+ debugfs_create_file("reset_tx_stats", 0600, dir, sta, -+ &fops_reset_tx_stats); -+ debugfs_create_file("driver_tx_pkts_flow", 0400, dir, sta, -+ &fops_driver_tx_pkts_flow); -+ } -+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) { - debugfs_create_file("rx_stats", 0400, dir, sta, - &fops_rx_stats); -+ debugfs_create_file("reset_rx_stats", 0600, dir, sta, -+ &fops_reset_rx_stats); -+ debugfs_create_file("driver_rx_pkts_flow", 0400, dir, sta, -+ &fops_driver_rx_pkts_flow); -+ } - - debugfs_create_file("htt_peer_stats", 0400, dir, sta, - &fops_htt_peer_stats); ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2416,6 +2416,7 @@ static void ath11k_dp_rx_h_mpdu(struct a - struct rx_attention *rx_attention; - u32 err_bitmap; - -+ - /* PN for multicast packets will be checked in mac80211 */ - rxcb = ATH11K_SKB_RXCB(msdu); - fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); -@@ -2609,6 +2610,7 @@ static void ath11k_dp_rx_deliver_msdu(st - struct ieee80211_rx_status *rx_status; - struct ieee80211_radiotap_he *he = NULL; - struct ieee80211_sta *pubsta = NULL; -+ struct ath11k_sta *arsta = NULL; - struct ath11k_peer *peer; - struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); - u8 decap = DP_RX_DECAP_TYPE_RAW; -@@ -2674,6 +2676,18 @@ static void ath11k_dp_rx_deliver_msdu(st - rx_status->flag |= RX_FLAG_8023; - - ieee80211_rx_napi(ar->hw, pubsta, msdu, napi); -+ -+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) { -+ if (!(status->flag & RX_FLAG_ONLY_MONITOR)) { -+ spin_lock_bh(&ar->ab->base_lock); -+ if (peer && peer->sta) -+ arsta = -+ (struct ath11k_sta *)peer->sta->drv_priv; -+ spin_unlock_bh(&ar->ab->base_lock); -+ if (arsta) -+ atomic_inc(&arsta->drv_rx_pkts.pkts_out); -+ } -+ } - } - - static int ath11k_dp_rx_process_msdu(struct ath11k *ar, -@@ -2820,6 +2834,8 @@ int ath11k_dp_process_rx(struct ath11k_b - int total_msdu_reaped = 0; - struct hal_srng *srng; - struct sk_buff *msdu; -+ struct ath11k_peer *peer = NULL; -+ struct ath11k_sta *arsta = NULL; - bool done = false; - int buf_id, mac_id; - struct ath11k *ar; -@@ -2893,6 +2909,19 @@ try_again: - rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM, - desc->info0); - -+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar) && rxcb->peer_id) { -+ rcu_read_lock(); -+ spin_lock_bh(&ab->base_lock); -+ peer = ath11k_peer_find_by_id(ab, rxcb->peer_id); -+ if (peer && peer->sta) -+ arsta = -+ (struct ath11k_sta *)peer->sta->drv_priv; -+ spin_unlock_bh(&ab->base_lock); -+ if (arsta) -+ atomic_inc(&arsta->drv_rx_pkts.pkts_frm_hw); -+ rcu_read_unlock(); -+ } -+ - rxcb->mac_id = mac_id; - __skb_queue_tail(&msdu_list[mac_id], msdu); - -@@ -4084,7 +4113,10 @@ static int ath11k_dp_rx_h_null_q_desc(st - struct rx_attention *rx_attention; - u8 l3pad_bytes; - struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); -+ struct ath11k_peer *peer = NULL; -+ struct ath11k_sta *arsta = NULL; - u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -+ u32 peer_id; - - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc); - -@@ -4136,6 +4168,18 @@ static int ath11k_dp_rx_h_null_q_desc(st - * rx with mac80211. Need not worry about cleaning up amsdu_list. - */ - -+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) { -+ peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, desc); -+ spin_lock_bh(&ar->ab->base_lock); -+ if (peer_id) -+ peer = ath11k_peer_find_by_id(ar->ab, rxcb->peer_id); -+ if (peer && peer->sta) -+ arsta = (struct ath11k_sta *)peer->sta->drv_priv; -+ spin_unlock_bh(&ar->ab->base_lock); -+ if (arsta) -+ atomic_inc(&arsta->drv_rx_pkts.pkts_frm_hw); -+ } -+ - return 0; - } - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6252,6 +6252,7 @@ static void ath11k_mac_op_tx(struct ieee - struct ath11k_mgmt_frame_stats *mgmt_stats = &arvif->mgmt_stats; - struct ath11k_sta *arsta = NULL; - u32 info_flags = info->flags; -+ struct ieee80211_sta *sta = control->sta; - bool is_prb_rsp; - u16 frm_type = 0; - int ret; -@@ -6314,6 +6315,15 @@ static void ath11k_mac_op_tx(struct ieee - ieee80211_free_txskb(ar->hw, skb); - return; - } -+ -+ if (ath11k_debugfs_is_extd_tx_stats_enabled(ar) && sta) { -+ arsta = (struct ath11k_sta *)sta->drv_priv; -+ if (arsta) { -+ atomic_inc(&arsta->drv_tx_pkts.pkts_in); -+ if (!ret) -+ atomic_inc(&arsta->drv_tx_pkts.pkts_out); -+ } -+ } - } - - void ath11k_mac_drain_tx(struct ath11k *ar) diff --git a/package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch b/package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch deleted file mode 100644 index 7488f0c2bf..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/234-002-mac80211-account-tx-rx-packets-flow.patch +++ /dev/null @@ -1,369 +0,0 @@ -From 26bf6027fe93346f47358e8933e613ac1ece3455 Mon Sep 17 00:00:00 2001 -From: Maharaja Kennadyrajan -Date: Mon, 4 Jan 2021 23:50:37 +0530 -Subject: [PATCH 2/2] ath11k/mac80211: Add support to account Tx and Rx flow - packets - -Added support to log the inflow and outflow of the Tx and Rx -packets in netif and host driver. - -Command to dump the Tx pkts flow in driver: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/driver_tx_pkts_flow - -Command to dump the Rx pkts flow in driver: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/driver_rx_pkts_flow - -Commands to reset the Tx/Rx pkts flow in driver: -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_tx_stats - -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_rx_stats - -Command to dump the Tx pkts flow in mac80211: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/mac80211_tx_pkts_flow - -Command to dump the Rx pkts flow in mac80211: -cat -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/mac80211_rx_pkts_flow - -Commands to reset the Tx/Rx pkts flow in mac80211: -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_mac80211_tx_pkts_flow - -echo 1 > -/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations/ -XX\:XX\:XX\:XX\:XX\:XX/reset_mac80211_rx_pkts_flow - -Sample output after running the Tx and Rx traffic. - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/driver_tx_pkts_flow -Tx packets inflow from mac80211: 20 -Tx packets outflow to HW: 20 - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/mac80211_tx_pkts_flow -Tx packets outflow from netif: 20 -Tx packets inflow in mac80211: 20 - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/driver_rx_pkts_flow -Rx packets inflow from HW: 28 -Rx packets outflow from driver: 28 - -root@OpenWrt:/# cat sys/kernel/debug/ieee80211/phy0/netdev\: -wlan0/stations/8c\:fd\:f0\:06\:23\:41/mac80211_rx_pkts_flow -Rx packets inflow in mac80211: 28 -Rx packets inflow in netif: 26 -Rx forwarded packets in bridge: 2 - -Signed-off-by: Maharaja Kennadyrajan ---- - net/mac80211/debugfs_sta.c | 174 +++++++++++++++++++++++++++++++++++++ - net/mac80211/rx.c | 13 +++ - net/mac80211/sta_info.h | 7 ++ - net/mac80211/tx.c | 8 ++ - 4 files changed, 202 insertions(+) - ---- a/net/mac80211/debugfs_sta.c -+++ b/net/mac80211/debugfs_sta.c -@@ -1219,6 +1219,176 @@ out: - } - LINK_STA_OPS(eht_capa); - -+static ssize_t -+sta_reset_mac80211_tx_pkts_flow_read(struct file *file, -+ char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ size_t bufsz = 30; -+ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; -+ ssize_t rv; -+ -+ if (!buf) -+ return -ENOMEM; -+ -+ p += scnprintf(p, bufsz + buf - p, "write 1 to reset the stats\n"); -+ -+ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); -+ kfree(buf); -+ return rv; -+} -+ -+static ssize_t -+sta_reset_mac80211_tx_pkts_flow_write(struct file *file, -+ const char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ struct sta_info *sta = file->private_data; -+ unsigned long tx_stats_reset; -+ int ret; -+ char _buf[2] = {}, *buf = _buf; -+ -+ if (count > sizeof(_buf)) -+ return -EINVAL; -+ -+ if (copy_from_user(buf, userbuf, count)) -+ return -EFAULT; -+ -+ buf[sizeof(_buf) - 1] = '\0'; -+ if (sscanf(buf, "%lu", &tx_stats_reset) != 1) -+ return -EINVAL; -+ -+ ret = kstrtoul(buf, 0, &tx_stats_reset); -+ if (ret || tx_stats_reset != 1) -+ return -EINVAL; -+ -+ atomic_set(&sta->tx_drv_pkts, 0); -+ atomic_set(&sta->tx_netif_pkts, 0); -+ -+ return count; -+} -+STA_OPS_RW(reset_mac80211_tx_pkts_flow); -+ -+static ssize_t -+sta_reset_mac80211_rx_pkts_flow_read(struct file *file, -+ char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ size_t bufsz = 30; -+ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; -+ ssize_t rv; -+ -+ if (!buf) -+ return -ENOMEM; -+ -+ p += scnprintf(p, bufsz + buf - p, "write 1 to reset the stats\n"); -+ -+ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); -+ kfree(buf); -+ return rv; -+} -+ -+static ssize_t -+sta_reset_mac80211_rx_pkts_flow_write(struct file *file, -+ const char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ struct sta_info *sta = file->private_data; -+ unsigned long rx_stats_reset; -+ int ret; -+ char _buf[2] = {}, *buf = _buf; -+ -+ if (count > sizeof(_buf)) -+ return -EINVAL; -+ -+ if (copy_from_user(buf, userbuf, count)) -+ return -EFAULT; -+ -+ buf[sizeof(_buf) - 1] = '\0'; -+ if (sscanf(buf, "%lu", &rx_stats_reset) != 1) -+ return -EINVAL; -+ -+ ret = kstrtoul(buf, 0, &rx_stats_reset); -+ if (ret || rx_stats_reset != 1) -+ return -EINVAL; -+ -+ atomic_set(&sta->rx_drv_pkts, 0); -+ atomic_set(&sta->rx_netif_pkts, 0); -+ atomic_set(&sta->rx_forwarded_pkts, 0); -+ -+ return count; -+} -+STA_OPS_RW(reset_mac80211_rx_pkts_flow); -+ -+static ssize_t sta_mac80211_tx_pkts_flow_read(struct file *file, -+ char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ struct sta_info *sta = file->private_data; -+ int retval = 0, len = 0; -+ const int size = 256; -+ char *buf; -+ -+ buf = kzalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ rcu_read_lock(); -+ -+ len += scnprintf(buf + len, size - len, -+ "Tx packets outflow from netif: %u\n", -+ atomic_read(&sta->tx_netif_pkts)); -+ len += scnprintf(buf + len, size - len, -+ "Tx packets outflow from mac80211: %u\n", -+ atomic_read(&sta->tx_drv_pkts)); -+ rcu_read_unlock(); -+ -+ if (len > size) -+ len = size; -+ -+ retval = simple_read_from_buffer(userbuf, count, ppos, buf, len); -+ kfree(buf); -+ -+ return retval; -+} -+STA_OPS(mac80211_tx_pkts_flow); -+ -+static ssize_t sta_mac80211_rx_pkts_flow_read(struct file *file, -+ char __user *userbuf, -+ size_t count, loff_t *ppos) -+{ -+ struct sta_info *sta = file->private_data; -+ int retval = 0, len = 0; -+ const int size = 512; -+ char *buf; -+ -+ buf = kzalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ rcu_read_lock(); -+ -+ len += scnprintf(buf + len, size - len, -+ "Rx packets inflow in mac80211: %u\n", -+ atomic_read(&sta->rx_drv_pkts)); -+ len += scnprintf(buf + len, size - len, -+ "Rx packets inflow in netif: %u\n", -+ atomic_read(&sta->rx_netif_pkts)); -+ len += scnprintf(buf + len, size - len, -+ "Rx forwarded packets in bridge: %u\n", -+ atomic_read(&sta->rx_forwarded_pkts)); -+ -+ rcu_read_unlock(); -+ -+ if (len > size) -+ len = size; -+ retval = simple_read_from_buffer(userbuf, count, ppos, buf, len); -+ kfree(buf); -+ -+ return retval; -+} -+STA_OPS(mac80211_rx_pkts_flow); -+ - #define DEBUGFS_ADD(name) \ - debugfs_create_file(#name, 0400, \ - sta->debugfs_dir, sta, &sta_ ##name## _ops) -@@ -1254,6 +1424,10 @@ void ieee80211_sta_debugfs_add(struct st - DEBUGFS_ADD(num_ps_buf_frames); - DEBUGFS_ADD(last_seq_ctrl); - DEBUGFS_ADD(agg_status); -+ DEBUGFS_ADD(reset_mac80211_tx_pkts_flow); -+ DEBUGFS_ADD(reset_mac80211_rx_pkts_flow); -+ DEBUGFS_ADD(mac80211_tx_pkts_flow); -+ DEBUGFS_ADD(mac80211_rx_pkts_flow); - /* FIXME: Kept here as the statistics are only done on the deflink */ - DEBUGFS_ADD_COUNTER(tx_filtered, deflink.status_stats.filtered); - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2623,6 +2623,7 @@ static void ieee80211_deliver_skb_to_loc - { - struct ieee80211_sub_if_data *sdata = rx->sdata; - struct net_device *dev = sdata->dev; -+ struct sta_info *sta = rx->sta; - - if (unlikely((skb->protocol == sdata->control_port_protocol || - (skb->protocol == cpu_to_be16(ETH_P_PREAUTH) && -@@ -2666,6 +2667,7 @@ static void ieee80211_deliver_skb_to_loc - else - netif_receive_skb(skb); - #endif -+ atomic_inc(&sta->rx_netif_pkts); - } - } - -@@ -2724,6 +2726,7 @@ ieee80211_deliver_skb(struct ieee80211_r - */ - xmit_skb = skb; - skb = NULL; -+ atomic_inc(&rx->sta->rx_forwarded_pkts); - } - } - } -@@ -4836,6 +4839,7 @@ static void ieee80211_rx_8023(struct iee - skb_reset_network_header(xmit_skb); - skb_reset_mac_header(xmit_skb); - dev_queue_xmit(xmit_skb); -+ atomic_inc(&rx->sta->rx_forwarded_pkts); - } - - if (!skb) -@@ -5332,9 +5336,18 @@ void ieee80211_rx_list(struct ieee80211_ - struct ieee80211_supported_band *sband; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ struct sta_info *sta = NULL; - - WARN_ON_ONCE(softirq_count() == 0); - -+ if (pubsta) { -+ sta = container_of(pubsta, struct sta_info, sta); -+ if (sta && napi) { -+ if (!(status->flag & RX_FLAG_ONLY_MONITOR)) -+ atomic_inc(&sta->rx_drv_pkts); -+ } -+ } -+ - if (WARN_ON(status->band >= NUM_NL80211_BANDS)) - goto drop; - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -724,6 +724,13 @@ struct sta_info { - struct link_sta_info deflink; - struct link_sta_info __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; - -+ atomic_t tx_drv_pkts; -+ atomic_t tx_netif_pkts; -+ atomic_t rx_drv_pkts; -+ atomic_t rx_netif_pkts; -+ /* Rx packets forwarded to bridge */ -+ atomic_t rx_forwarded_pkts; -+ - /* keep last! */ - struct ieee80211_sta sta; - }; ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -4294,6 +4294,9 @@ void __ieee80211_subif_start_xmit(struct - if (IS_ERR(sta)) - sta = NULL; - -+ if (sta) -+ atomic_inc(&sta->tx_netif_pkts); -+ - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { - ap_sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, u.ap); -@@ -4614,6 +4617,9 @@ static bool __ieee80211_tx_8023(struct i - - drv_tx(local, &control, skb); - -+ if (sta) -+ atomic_inc(&sta->tx_drv_pkts); -+ - return true; - } - -@@ -4719,6 +4725,9 @@ static void ieee80211_8023_xmit(struct i - - ieee80211_tx_8023(sdata, skb, sta, false); - -+ if (sta) -+ atomic_inc(&sta->tx_netif_pkts); -+ - return; - - out_free: diff --git a/package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index 5d5a83911d..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/235-001-ath11k-Add-support-for-beacon-tx-mode.patch +++ /dev/null @@ -1,45 +0,0 @@ -From a297f43a9ad6d8c95cf8b984337ffb410f3eb92c Mon Sep 17 00:00:00 2001 -From: Maharaja Kennadyrajan -Date: Tue, 12 Jan 2021 18:07:51 +0530 -Subject: [PATCH] ath11k: Add support for beacon tx mode - -User can configure the beacon tx mode while bring-up the -AP via hostapd configuration. - -Use the below configuration in the hostapd to configure -the beacon tx mode. - -"beacon_tx_mode=N", where N = 0 for STAGGERED beacon mode -and N = 1 for BURST beacon mode. - -Signed-off-by: Maharaja Kennadyrajan ---- - drivers/net/wireless/ath/ath11k/mac.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3481,7 +3481,10 @@ static void ath11k_mac_op_bss_info_chang - - if (changed & BSS_CHANGED_BEACON) { - param_id = WMI_PDEV_PARAM_BEACON_TX_MODE; -- param_value = WMI_BEACON_STAGGERED_MODE; -+ if (info->beacon_tx_mode == NL80211_BEACON_BURST_MODE) -+ param_value = WMI_BEACON_BURST_MODE; -+ else -+ param_value = WMI_BEACON_STAGGERED_MODE; - ret = ath11k_wmi_pdev_set_param(ar, param_id, - param_value, ar->pdev->pdev_id); - if (ret) -@@ -3489,8 +3492,9 @@ static void ath11k_mac_op_bss_info_chang - arvif->vdev_id); - else - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, -- "Set staggered beacon mode for VDEV: %d\n", -- arvif->vdev_id); -+ "Set %s beacon mode for VDEV: %d mode: %d\n", -+ param_value ? "burst" : "staggered", -+ arvif->vdev_id, param_value); - - if (!arvif->do_not_send_tmpl || !arvif->bcca_zero_sent) { - ret = ath11k_mac_setup_bcn_tmpl(arvif); diff --git a/package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch deleted file mode 100644 index 6fb460f6b4..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/235-002-mac80211-Add-support-for-beacon-tx-mode.patch +++ /dev/null @@ -1,159 +0,0 @@ -From f8e7ec408c357d6438abd980f700353a7efcac7e Mon Sep 17 00:00:00 2001 -From: Maharaja Kennadyrajan -Date: Tue, 12 Jan 2021 18:11:33 +0530 -Subject: [PATCH] mac80211: Add support for beacon tx mode - -User can configure the beacon tx mode while bring-up the -AP via hostapd configuration. - -Use the below configuration in the hostapd to configure -the beacon tx mode. - -"beacon_tx_mode=N", where N = 0 for STAGGERED beacon mode -and N = 1 for BURST beacon mode. - -Signed-off-by: Maharaja Kennadyrajan ---- - include/net/cfg80211.h | 2 +- - include/net/mac80211.h | 1 + - include/uapi/linux/nl80211.h | 2 ++ - net/mac80211/cfg.c | 1 + - net/wireless/nl80211.c | 7 ++++++- - 5 files changed, 11 insertions(+), 2 deletions(-) - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -1443,6 +1443,7 @@ struct cfg80211_unsol_bcast_probe_resp { - * @punct_bitmap: Preamble puncturing bitmap. Each bit represents - * a 20 MHz channel, lowest bit corresponding to the lowest channel. - * Bit set to 1 indicates that the channel is punctured. -+ * @beacon_tx_mode: Beacon Tx Mode setting - */ - struct cfg80211_ap_settings { - struct cfg80211_chan_def chandef; -@@ -1478,6 +1479,7 @@ struct cfg80211_ap_settings { - struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; - struct cfg80211_mbssid_config mbssid_config; - u16 punct_bitmap; -+ enum nl80211_beacon_tx_mode beacon_tx_mode; - }; - - /** -@@ -2436,6 +2438,7 @@ struct mesh_config { - * to operate on DFS channels. - * @control_port_over_nl80211: TRUE if userspace expects to exchange control - * port frames over NL80211 instead of the network interface. -+ * @beacon_tx_mode: Beacon Tx Mode setting. - * - * These parameters are fixed when the mesh is created. - */ -@@ -2459,6 +2462,7 @@ struct mesh_setup { - struct cfg80211_bitrate_mask beacon_rate; - bool userspace_handles_dfs; - bool control_port_over_nl80211; -+ enum nl80211_beacon_tx_mode beacon_tx_mode; - }; - - /** ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -698,6 +698,7 @@ struct ieee80211_fils_discovery { - * @eht_mu_beamformer: in AP-mode, does this BSS enable operation as an EHT MU - * beamformer - * @nss_ap_isolate: Used for notifying the NSS host about AP isolate feature -+ * @beacon_tx_mode: Beacon Tx Mode setting. - */ - struct ieee80211_bss_conf { - struct ieee80211_vif *vif; -@@ -792,6 +793,7 @@ struct ieee80211_bss_conf { - bool eht_su_beamformee; - bool eht_mu_beamformer; - bool nss_ap_isolate; -+ enum nl80211_beacon_tx_mode beacon_tx_mode; - }; - - /** ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -2814,7 +2814,9 @@ enum nl80211_commands { - * - * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is - * disabled. -- * -+ * @NL80211_ATTR_BEACON_TX_MODE: used to configure the beacon tx mode as -+ * staggered mode = 1 or burst mode = 2 in %NL80211_CMD_START_AP or -+ * %NL80211_CMD_JOIN_MESH from user-space. - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3353,6 +3355,8 @@ enum nl80211_attrs { - - NL80211_ATTR_MLO_LINK_DISABLED, - -+ NL80211_ATTR_BEACON_TX_MODE, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -7840,4 +7844,12 @@ enum nl80211_ap_settings_flags { - NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1, - }; - -+/** -+ * enum nl80211_beacon_tx_mode - Beacon Tx Mode enum. -+ * Used to configure beacon staggered mode or beacon burst mode. -+ */ -+enum nl80211_beacon_tx_mode { -+ NL80211_BEACON_STAGGERED_MODE = 1, -+ NL80211_BEACON_BURST_MODE = 2, -+}; - #endif /* __LINUX_NL80211_H */ ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1294,6 +1294,7 @@ static int ieee80211_start_ap(struct wip - - prev_beacon_int = link_conf->beacon_int; - link_conf->beacon_int = params->beacon_interval; -+ link_conf->beacon_tx_mode = params->beacon_tx_mode; - - if (params->ht_cap) - link_conf->ht_ldpc = -@@ -2490,6 +2491,7 @@ static int copy_mesh_setup(struct ieee80 - - sdata->vif.bss_conf.beacon_int = setup->beacon_interval; - sdata->vif.bss_conf.dtim_period = setup->dtim_period; -+ sdata->vif.bss_conf.beacon_tx_mode = setup->beacon_tx_mode; - - sdata->beacon_rate_set = false; - if (wiphy_ext_feature_isset(sdata->local->hw.wiphy, ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -811,6 +811,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG }, - [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED }, - [NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG }, -+ [NL80211_ATTR_BEACON_TX_MODE] = NLA_POLICY_RANGE(NLA_U32, 1, 2), - }; - - /* policy for the key attributes */ -@@ -5941,6 +5942,9 @@ static int nl80211_start_ap(struct sk_bu - nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); - params->dtim_period = - nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); -+ if (info->attrs[NL80211_ATTR_BEACON_TX_MODE]) -+ params->beacon_tx_mode = -+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_TX_MODE]); - - err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype, - params->beacon_interval); -@@ -13037,6 +13041,10 @@ static int nl80211_join_mesh(struct sk_b - return -EINVAL; - } - -+ if (info->attrs[NL80211_ATTR_BEACON_TX_MODE]) -+ setup.beacon_tx_mode = -+ nla_get_u32(info->attrs[NL80211_ATTR_BEACON_TX_MODE]); -+ - if (info->attrs[NL80211_ATTR_MESH_SETUP]) { - /* parse additional setup parameters if given */ - err = nl80211_parse_mesh_setup(info, &setup); diff --git a/package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch b/package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch deleted file mode 100644 index 83c019b871..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/237-002-ath11k-Add-provision-to-configure-rx-hashmap.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 60d0a63d537c280ff9501296cefd322b981b88f5 Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Mon, 14 Dec 2020 19:13:49 +0530 -Subject: [PATCH] ath11k: Add provision to configure rx hashmap - -Currently the hashmap is set to default during REO -setup and all REO rings are equally distributed across -32 hash values. - -Add provision to configure the hashmap so that destination -rings can be controlled. Setting 0 will disable hash based -steering. - -echo "hashmap" > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/rx_hash - -Signed-off-by: Sriram R -Signed-off-by: P Praneesh ---- - drivers/net/wireless/ath/ath11k/core.h | 2 ++ - drivers/net/wireless/ath/ath11k/debugfs.c | 51 ++++++++++++++++++++++++++++++++ - drivers/net/wireless/ath/ath11k/dp.c | 4 ++- - drivers/net/wireless/ath/ath11k/hal.h | 1 + - drivers/net/wireless/ath/ath11k/hal_rx.c | 30 +++++++++++-------- - 5 files changed, 74 insertions(+), 14 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -65,6 +65,7 @@ extern bool ath11k_ftm_mode; - #define ATH11K_RECONFIGURE_TIMEOUT_HZ (10 * HZ) - #define ATH11K_RECOVER_START_TIMEOUT_HZ (20 * HZ) - -+#define HAL_REO_DEST_RING_CTRL_HASH_RING_SHIFT 8 - enum ath11k_supported_bw { - ATH11K_BW_20 = 0, - ATH11K_BW_40 = 1, -@@ -1037,6 +1038,8 @@ struct ath11k_base { - atomic_t num_max_allowed; - struct ath11k_num_vdevs_peers *num_vdevs_peers; - -+ u32 rx_hash; -+ - /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); - }; ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -972,6 +972,54 @@ static const struct file_operations fops - .llseek = default_llseek, - }; - -+static ssize_t ath11k_write_rx_hash(struct file *file, -+ const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k_base *ab = file->private_data; -+ struct ath11k_pdev *pdev; -+ u32 rx_hash; -+ u8 buf[128] = {0}; -+ int ret, i, radioup = 0; -+ -+ for (i = 0; i < ab->num_radios; i++) { -+ pdev = &ab->pdevs[i]; -+ if (pdev && pdev->ar) { -+ radioup = 1; -+ break; -+ } -+ } -+ -+ if (radioup == 0) { -+ ath11k_err(ab, "radio is not up\n"); -+ ret = -ENETDOWN; -+ goto exit; -+ } -+ -+ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count); -+ if (ret < 0) -+ goto exit; -+ -+ buf[ret] = '\0'; -+ ret = sscanf(buf, "%x", &rx_hash); -+ if (!ret) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ if (rx_hash != ab->rx_hash) { -+ ab->rx_hash = rx_hash; -+ if (rx_hash) -+ ath11k_hal_reo_hash_setup(ab, rx_hash); -+ } -+ ret = count; -+exit: -+ return ret; -+} -+static const struct file_operations fops_soc_rx_hash = { -+ .open = simple_open, -+ .write = ath11k_write_rx_hash, -+}; - int ath11k_debugfs_pdev_create(struct ath11k_base *ab) - { - if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) -@@ -987,6 +1035,10 @@ int ath11k_debugfs_pdev_create(struct at - debugfs_create_file("sram", 0400, ab->debugfs_soc, ab, - &fops_sram_dump); - -+ debugfs_create_file("rx_hash", 0600, ab->debugfs_soc, ab, -+ &fops_soc_rx_hash); -+ -+ - return 0; - } - ---- a/drivers/net/wireless/ath/ath11k/dp.c -+++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -50,7 +50,7 @@ int ath11k_dp_peer_setup(struct ath11k * - bool rx_hash_enable = DP_RX_HASH_ENABLE; - - /* RX Hash based steering is disabled for NSS Offload */ -- if (ar->ab->nss.enabled) -+ if (ar->ab->nss.enabled || !ab->rx_hash) - rx_hash_enable = DP_RX_HASH_DISABLE; - - /* NOTE: reo_dest ring id starts from 1 unlike mac_id which starts from 0 */ ---- a/drivers/net/wireless/ath/ath11k/hal.h -+++ b/drivers/net/wireless/ath/ath11k/hal.h -@@ -922,6 +922,7 @@ void ath11k_hal_reo_qdesc_setup(void *va - u32 start_seq, enum hal_pn_type type); - void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab, - struct hal_srng *srng); -+void ath11k_hal_reo_hash_setup(struct ath11k_base *ab, u32 ring_hash_map); - void ath11k_hal_setup_link_idle_list(struct ath11k_base *ab, - struct hal_wbm_idle_scatter_list *sbuf, - u32 nsbufs, u32 tot_link_desc, ---- a/drivers/net/wireless/ath/ath11k/hw.c -+++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -102,6 +102,23 @@ static void ath11k_init_wmi_config_qca63 - config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; - } - -+void ath11k_hal_reo_hash_setup(struct ath11k_base *ab, u32 ring_hash_map) -+{ -+ u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG; -+ u8 reo_dest_hash_shift = ab->hw_params.reo_dest_ring_map_shift; -+ -+ ab->rx_hash = ring_hash_map; -+ -+ /* These registers use only 24bits(3 bits x 8 hash values) for -+ * mapping the dest rings and remaining bits are reserved/not used -+ * so its safe to write them completely. -+ */ -+ ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, -+ ring_hash_map << reo_dest_hash_shift); -+ ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, -+ ring_hash_map << reo_dest_hash_shift); -+} -+ - static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) - { - u8 frag_dest_ring = HAL_SRNG_RING_ID_REO2SW1; -@@ -143,18 +160,7 @@ static void ath11k_hw_ipq8074_reo_setup( - if (ab->nss.enabled) - return; - -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, -- FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, -- ring_hash_map)); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, -- FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, -- ring_hash_map)); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, -- FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, -- ring_hash_map)); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, -- FIELD_PREP(HAL_REO_DEST_RING_CTRL_HASH_RING_MAP, -- ring_hash_map)); -+ ath11k_hal_reo_hash_setup(ab, ring_hash_map); - } - - static void ath11k_init_wmi_config_ipq8074(struct ath11k_base *ab, -@@ -925,10 +931,7 @@ static void ath11k_hw_wcn6855_reo_setup( - if (ab->nss.enabled) - return; - -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, -- ring_hash_map); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, -- ring_hash_map); -+ ath11k_hal_reo_hash_setup(ab, ring_hash_map); - } - - static void ath11k_hw_ipq5018_reo_setup(struct ath11k_base *ab) -@@ -963,15 +966,7 @@ static void ath11k_hw_ipq5018_reo_setup( - HAL_DEFAULT_REO_TIMEOUT_USEC); - ath11k_hif_write32(ab, reo_base + HAL_REO1_AGING_THRESH_IX_3(ab), - HAL_DEFAULT_REO_TIMEOUT_USEC); -- -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_0, -- ring_hash_map); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_1, -- ring_hash_map); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_2, -- ring_hash_map); -- ath11k_hif_write32(ab, reo_base + HAL_REO1_DEST_RING_CTRL_IX_3, -- ring_hash_map); -+ ath11k_hal_reo_hash_setup(ab, ring_hash_map); - } - - static u16 diff --git a/package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch b/package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch deleted file mode 100644 index 6f7c1aadd9..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/245-revert-dev-sw-netstats-txrx-add.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 3be7ae2d65b6638c4165d66c1c4b5d82d95517d9 Mon Sep 17 00:00:00 2001 -From: Tamizh Chelvam -Date: Wed, 10 Mar 2021 12:21:49 +0530 -Subject: [PATCH] Revert "net: mac80211: use core API for updating TX/RX stats" - -This reverts 36ec144f041bedc2f14b32faa2da11d4d9660003 commit -in QSDK since 4.4 backports does not support netstats APIs -for tx/rx stats and retaining the original logic for calculating -tx/rx stats. - -Signed-off-by: Tamizh Chelvam ---- - net/mac80211/rx.c | 18 ++++++++++++++---- - net/mac80211/tx.c | 16 +++++++++++++--- - 2 files changed, 27 insertions(+), 7 deletions(-) - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -33,6 +33,18 @@ - #include "wme.h" - #include "rate.h" - -+static inline void ieee80211_rx_stats(struct net_device *dev, u32 len) -+{ -+ struct pcpu_sw_netstats *tstats = this_cpu_ptr(netdev_tstats(dev)); -+ -+ u64_stats_update_begin(&tstats->syncp); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) -+ tstats->rx_packets++; -+ tstats->rx_bytes += len; -+#endif -+ u64_stats_update_end(&tstats->syncp); -+} -+ - /* - * monitor mode reception - * -@@ -50,7 +62,11 @@ static struct sk_buff *ieee80211_clean_s - - if (present_fcs_len) - __pskb_trim(skb, skb->len - present_fcs_len); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) -+ __pskb_pull(skb, rtap_space); -+#else - pskb_pull(skb, rtap_space); -+#endif - - /* After pulling radiotap header, clear all flags that indicate - * info in skb->data. -@@ -83,7 +99,11 @@ static struct sk_buff *ieee80211_clean_s - - memmove(skb->data + IEEE80211_HT_CTL_LEN, skb->data, - hdrlen - IEEE80211_HT_CTL_LEN); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) -+ __pskb_pull(skb, IEEE80211_HT_CTL_LEN); -+#else - pskb_pull(skb, IEEE80211_HT_CTL_LEN); -+#endif - - return skb; - } -@@ -853,7 +873,7 @@ ieee80211_rx_monitor(struct ieee80211_lo - - if (skb) { - skb->dev = sdata->dev; -- dev_sw_netstats_rx_add(skb->dev, skb->len); -+ ieee80211_rx_stats(skb->dev, skb->len); - netif_receive_skb(skb); - } - } -@@ -2686,7 +2706,7 @@ ieee80211_deliver_skb(struct ieee80211_r - skb = rx->skb; - xmit_skb = NULL; - -- dev_sw_netstats_rx_add(dev, skb->len); -+ ieee80211_rx_stats(dev, skb->len); - - if (rx->sta) { - /* The seqno index has the same property as needed -@@ -4098,7 +4118,7 @@ static void ieee80211_rx_cooked_monitor( - } - - prev_dev = sdata->dev; -- dev_sw_netstats_rx_add(sdata->dev, skb->len); -+ ieee80211_rx_stats(sdata->dev, skb->len); - } - - if (prev_dev) { -@@ -4806,7 +4826,7 @@ static void ieee80211_rx_8023(struct iee - - skb->dev = fast_rx->dev; - -- dev_sw_netstats_rx_add(fast_rx->dev, skb->len); -+ ieee80211_rx_stats(fast_rx->dev, skb->len); - - /* The seqno index has the same property as needed - * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -40,6 +40,18 @@ - static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, - struct net_device *dev, struct sta_info *sta, - struct ieee80211_key *key, struct sk_buff *skb); -+ -+static inline void ieee80211_tx_stats(struct net_device *dev, u32 len) -+{ -+ struct pcpu_sw_netstats *tstats = this_cpu_ptr(netdev_tstats(dev)); -+ -+ u64_stats_update_begin(&tstats->syncp); -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)) -+ tstats->tx_packets++; -+ tstats->tx_bytes += len; -+#endif -+ u64_stats_update_end(&tstats->syncp); -+} - /* misc utils */ - - static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -3557,7 +3569,7 @@ ieee80211_xmit_fast_finish(struct ieee80 - if (key) - info->control.hw_key = &key->conf; - -- dev_sw_netstats_tx_add(skb->dev, 1, skb->len); -+ ieee80211_tx_stats(skb->dev, skb->len); - - if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -@@ -4346,7 +4358,7 @@ void __ieee80211_subif_start_xmit(struct - goto out; - } - -- dev_sw_netstats_tx_add(dev, 1, skb->len); -+ ieee80211_tx_stats(dev, skb->len); - - ieee80211_xmit(sdata, sta, skb); - } -@@ -4717,7 +4729,7 @@ static void ieee80211_8023_xmit(struct i - info->ack_frame_id = ieee80211_store_ack_skb(local, skb, - &info->flags, NULL); - -- dev_sw_netstats_tx_add(dev, skbs, len); -+ ieee80211_tx_stats(dev, len); - if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { - sta->deflink.tx_stats.packets[queue] += skbs; - sta->deflink.tx_stats.bytes[queue] += len; diff --git a/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch b/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch deleted file mode 100644 index d8c9075566..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/359-ath11k-fix-tkip-encryption-traffic-failure.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e4f2f898dcbe2bf82b9e8fb4f3d306c98d82e5bd Mon Sep 17 00:00:00 2001 -From: Ramya Gnanasekar -Date: Wed, 7 Dec 2022 17:29:50 +0530 -Subject: [PATCH] ath11k: fix tkip encryption traffic failure - -Fast rx is not assigned in case of TKIP cipher and hence -packets are dropped in fast path. - -Handle the rx decap for TKIP so frames will be handled in -normal rx path. - -Signed-off-by: Ramya Gnanasekar - ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2364,7 +2364,8 @@ static void ath11k_dp_rx_h_undecap(struc - ehdr = (struct ethhdr *)msdu->data; - - /* mac80211 allows fast path only for authorized STA */ -- if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) { -+ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE) || -+ enctype == HAL_ENCRYPT_TYPE_TKIP_MIC) { - ATH11K_SKB_RXCB(msdu)->is_eapol = true; - ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr, - enctype, status); diff --git a/package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch b/package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch deleted file mode 100644 index 79146df544..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/640-006-mac80211-add-eht-radiotap.patch +++ /dev/null @@ -1,506 +0,0 @@ -From f76abd98383dbd350f4e41b400beaaff2130254a Mon Sep 17 00:00:00 2001 -From: P Praneesh -Date: Sun, 3 Jul 2022 19:31:44 +0530 -Subject: [PATCH] mac80211: add EHT radiotap header construction logic - -Driver advertises U_SIG and EHT info in the flag under rx_status -structure. Based on this flag, corresponding EHT and U_SIG -information are added in the radiotap header. - -Signed-off-by: P Praneesh ---- - include/net/ieee80211_radiotap.h | 160 +++++++++++++++++++++++++++++++++++++++ - include/net/mac80211.h | 9 +++ - net/mac80211/rx.c | 88 +++++++++++++++++++++ - 3 files changed, 257 insertions(+) - ---- a/include/net/ieee80211_radiotap.h -+++ b/include/net/ieee80211_radiotap.h -@@ -92,6 +92,11 @@ enum ieee80211_radiotap_presence { - IEEE80211_RADIOTAP_EHT = 34, - }; - -+enum ieee80211_radiotap_presence_ext { -+ IEEE80211_RADIOTAP_USIG_INFO = 1, -+ IEEE80211_RADIOTAP_EHT_INFO = 2, -+}; -+ - /* for IEEE80211_RADIOTAP_FLAGS */ - enum ieee80211_radiotap_flags { - IEEE80211_RADIOTAP_F_CFP = 0x01, -@@ -406,128 +411,6 @@ struct ieee80211_radiotap_eht_usig { - __le32 mask; - } __packed; - --/* ieee80211_radiotap_eht - content of EHT tlv (type 34) -- * see www.radiotap.org/fields/EHT.html for details -- */ --struct ieee80211_radiotap_eht { -- __le32 known; -- __le32 data[9]; -- __le32 user_info[]; --} __packed; -- --/* Known field for EHT TLV -- * The ending defines for what the field applies as following -- * O - OFDMA (including TB), M - MU-MIMO, S - EHT sounding. -- */ --enum ieee80211_radiotap_eht_known { -- IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE = 0x00000002, -- IEEE80211_RADIOTAP_EHT_KNOWN_GI = 0x00000004, -- IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF = 0x00000010, -- IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM = 0x00000020, -- IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM = 0x00000040, -- IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM = 0x00000080, -- IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O = 0x00000100, -- IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S = 0x00000200, -- IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 = 0x00002000, -- IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1 = 0x00004000, -- IEEE80211_RADIOTAP_EHT_KNOWN_CRC2_O = 0x00008000, -- IEEE80211_RADIOTAP_EHT_KNOWN_TAIL2_O = 0x00010000, -- IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S = 0x00020000, -- IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S = 0x00040000, -- IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M = 0x00080000, -- IEEE80211_RADIOTAP_EHT_KNOWN_ENCODING_BLOCK_CRC_M = 0x00100000, -- IEEE80211_RADIOTAP_EHT_KNOWN_ENCODING_BLOCK_TAIL_M = 0x00200000, -- IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM = 0x00400000, -- IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM = 0x00800000, -- IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT = 0x01000000, -- IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80 = 0x02000000, --}; -- --enum ieee80211_radiotap_eht_data { -- /* Data 0 */ -- IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE = 0x00000078, -- IEEE80211_RADIOTAP_EHT_DATA0_GI = 0x00000180, -- IEEE80211_RADIOTAP_EHT_DATA0_LTF = 0x00000600, -- IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF = 0x00003800, -- IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM = 0x00004000, -- IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM = 0x00018000, -- IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM = 0x00020000, -- IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S = 0x000c0000, -- IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O = 0x003c0000, -- IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O = 0x03c00000, -- IEEE80211_RADIOTAP_EHT_DATA0_TAIL1_O = 0xfc000000, -- /* Data 1 */ -- IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE = 0x0000001f, -- IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX = 0x00001fe0, -- IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1 = 0x003fe000, -- IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN = 0x00400000, -- IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80 = 0xc0000000, -- /* Data 2 */ -- IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_1 = 0x000001ff, -- IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_1_KNOWN = 0x00000200, -- IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2 = 0x0007fc00, -- IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN = 0x00080000, -- IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_2 = 0x1ff00000, -- IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_2_KNOWN = 0x20000000, -- /* Data 3 */ -- IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1 = 0x000001ff, -- IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN = 0x00000200, -- IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_2_2_1 = 0x0007fc00, -- IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_2_2_1_KNOWN = 0x00080000, -- IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2 = 0x1ff00000, -- IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN = 0x20000000, -- /* Data 4 */ -- IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_2 = 0x000001ff, -- IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_2_KNOWN = 0x00000200, -- IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3 = 0x0007fc00, -- IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN = 0x00080000, -- IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_3 = 0x1ff00000, -- IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_3_KNOWN = 0x20000000, -- /* Data 5 */ -- IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4 = 0x000001ff, -- IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN = 0x00000200, -- IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_2_2_4 = 0x0007fc00, -- IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_2_2_4_KNOWN = 0x00080000, -- IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5 = 0x1ff00000, -- IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN = 0x20000000, -- /* Data 6 */ -- IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_5 = 0x000001ff, -- IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_5_KNOWN = 0x00000200, -- IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6 = 0x0007fc00, -- IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN = 0x00080000, -- IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_6 = 0x1ff00000, -- IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_6_KNOWN = 0x20000000, -- /* Data 7 */ -- IEEE80211_RADIOTAP_EHT_DATA7_CRC2_O = 0x0000000f, -- IEEE80211_RADIOTAP_EHT_DATA7_TAIL_2_O = 0x000003f0, -- IEEE80211_RADIOTAP_EHT_DATA7_NSS_S = 0x0000f000, -- IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S = 0x00010000, -- IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS = 0x000e0000, -- IEEE80211_RADIOTAP_EHT_DATA7_USER_ENCODING_BLOCK_CRC = 0x00f00000, -- IEEE80211_RADIOTAP_EHT_DATA7_USER_ENCODING_BLOCK_TAIL = 0x3f000000, -- /* Data 8 */ -- IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_PS_160 = 0x00000001, -- IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0 = 0x00000002, -- IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1 = 0x000001fc, --}; -- --enum ieee80211_radiotap_eht_user_info { -- IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN = 0x00000001, -- IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN = 0x00000002, -- IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN = 0x00000004, -- IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O = 0x00000010, -- IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O = 0x00000020, -- IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M = 0x00000040, -- IEEE80211_RADIOTAP_EHT_USER_INFO_DATA_FOR_USER = 0x00000080, -- IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID = 0x0007ff00, -- IEEE80211_RADIOTAP_EHT_USER_INFO_CODING = 0x00080000, -- IEEE80211_RADIOTAP_EHT_USER_INFO_MCS = 0x00f00000, -- IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O = 0x0f000000, -- IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O = 0x20000000, -- IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M = 0x3f000000, -- IEEE80211_RADIOTAP_EHT_USER_INFO_RESEVED_c0000000 = 0xc0000000, --}; -- - enum ieee80211_radiotap_eht_usig_common { - IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN = 0x00000001, - IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN = 0x00000002, -@@ -573,6 +456,161 @@ enum ieee80211_radiotap_eht_usig_tb { - IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL = 0xfc000000, - }; - -+enum ieee80211_radiotap_usig_common { -+ IEEE80211_RADIOTAP_USIG_CMN_PHY_VERSION = 0x00000001, -+ IEEE80211_RADIOTAP_USIG_CMN_BW_KNOWN = 0x00000002, -+ IEEE80211_RADIOTAP_USIG_CMN_UL_DL_KNOWN = 0x00000004, -+ IEEE80211_RADIOTAP_USIG_CMN_BSS_COLOR_KNOWN = 0x00000008, -+ IEEE80211_RADIOTAP_USIG_CMN_TXOP_KNOWN = 0x00000010, -+ IEEE80211_RADIOTAP_USIG_CMN_BAD_CRC = 0x00000020, -+ IEEE80211_RADIOTAP_USIG_CMN_PHY_VERSION_ID = 0x00007000, -+ IEEE80211_RADIOTAP_USIG_CMN_BW = 0x00038000, -+ IEEE80211_RADIOTAP_USIG_CMN_UL_DL = 0x00040000, -+ IEEE80211_RADIOTAP_USIG_CMN_BSS_COLOR = 0x01f80000, -+ IEEE80211_RADIOTAP_USIG_CMN_TXOP = 0xfe000000, -+}; -+ -+enum ieee80211_radiotap_usig_eht_mu_ppdu { -+ IEEE80211_RADIOTAP_USIG_EHT_MU_DISREGARD = 0x0000001f, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_DISREGARD_VALIDATE = 0x00000020, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_PPDU_TYPE_COMP_MODE = 0x000000c0, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_PPDU_COMP_VALIDATE = 0x00000100, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_PUNCTURED_CHAN_INFO = 0x00003e00, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_PUNCTURED_CHAN_VALIDATE = 0x00004000, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_MCS = 0x00018000, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_NUM_SYMBOLS = 0x003e0000, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_CRC = 0x03c00000, -+ IEEE80211_RADIOTAP_USIG_EHT_MU_TAIL = 0xfc000000, -+}; -+ -+enum ieee80211_radiotap_usig_eht_tb_ppdu { -+ IEEE80211_RADIOTAP_USIG_EHT_TB_DISREGARD = 0x0000003f, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_PPDU_TYPE_COMP_MODE = 0x000000c0, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_VALIDATE = 0x00000100, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_SPATIAL_REUSE1 = 0x00001e00, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_SPATIAL_REUSE2 = 0x0001e000, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_DISREGARD1 = 0x003e0000, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_CRC = 0x03c00000, -+ IEEE80211_RADIOTAP_USIG_EHT_TB_TAIL = 0xfc000000, -+}; -+ -+struct ieee80211_radiotap_usig { -+ __le32 usig_cmn; -+ __le32 eht_mu_ppdu; -+ __le32 eht_tb_ppdu; -+}; -+ -+enum ieee80211_radiotap_eht_known { -+ IEEE80211_RADIOTAP_EHT_SPATIAL_REUSE_KNOWN = 0x00000002, -+ IEEE80211_RADIOTAP_EHT_GUARD_INTERVAL_KNOWN = 0x00000004, -+ IEEE80211_RADIOTAP_EHT_LTF_KNOWN = 0x00000008, -+ IEEE80211_RADIOTAP_EHT_EHT_LTF_KNOWN = 0x00000010, -+ IEEE80211_RADIOTAP_EHT_LDPC_EXTRA_SYM_SEG_KNOWN = 0x00000020, -+ IEEE80211_RADIOTAP_EHT_PRE_FEC_PAD_FACTOR_KNOWN = 0x00000040, -+ IEEE80211_RADIOTAP_EHT_PE_DISAMBIGUITY_KNOWN = 0x00000080, -+ IEEE80211_RADIOTAP_EHT_DISREGARD_KNOWN = 0x00000100, -+ IEEE80211_RADIOTAP_EHT_SOUNDING_DISREGARD_KNOWN = 0x00000200, -+ IEEE80211_RADIOTAP_EHT_CRC1_KNOWN = 0x00002000, -+ IEEE80211_RADIOTAP_EHT_TAIL1_KNOWN = 0x00004000, -+ IEEE80211_RADIOTAP_EHT_CRC2_KNOWN = 0x00008000, -+ IEEE80211_RADIOTAP_EHT_TAIL2_KNOWN = 0x00010000, -+ IEEE80211_RADIOTAP_EHT_NSS_KNOWN = 0x00020000, -+ IEEE80211_RADIOTAP_EHT_BEAMFORMED_KNOWN = 0x00040000, -+ IEEE80211_RADIOTAP_EHT_NUM_NON_OFDMA_USR_KNOWN = 0x00080000, -+ IEEE80211_RADIOTAP_EHT_USR_ENC_BLK_CRC_KNOWN = 0x00100000, -+ IEEE80211_RADIOTAP_EHT_USR_ENC_BLK_TAIL_KNOWN = 0x00200000, -+ IEEE80211_RADIOTAP_EHT_RU_SIZE_KNOWN = 0x00400000, -+ IEEE80211_RADIOTAP_EHT_RU_INDEX_KNOWN = 0x00800000, -+ IEEE80211_RADIOTAP_EHT_RU_ALLOCATION = 0x01000000, -+ IEEE80211_RADIOTAP_EHT_PRI80_CHAN_POS_KNOWN = 0x02000000, -+}; -+ -+enum ieee80211_radiotap_eht_data0 { -+ IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE = 0x00000078, -+ IEEE80211_RADIOTAP_EHT_DATA0_GI = 0x00000180, -+ IEEE80211_RADIOTAP_EHT_DATA0_LTF = 0x00000600, -+ IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF = 0x00003800, -+ IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_SEG = 0x00004000, -+ IEEE80211_RADIOTAP_EHT_DATA0_PRE_FEC_PAD_FACTOR = 0x00018000, -+ IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY = 0x00020000, -+ IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_EHT_SOUND = 0x000c0000, -+ IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_NON_EHT_SOUND = 0x003c0000, -+ IEEE80211_RADIOTAP_EHT_DATA0_CRC1 = 0x03c00000, -+ IEEE80211_RADIOTAP_EHT_DATA0_TAIL1 = 0xfc000000, -+}; -+ -+enum ieee80211_radiotap_eht_data1 { -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE = 0x0000001f, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_26 = 0, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_52 = 1, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_106 = 2, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_242 = 3, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_484 = 4, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_996 = 5, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_2x996 = 6, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_4x996 = 7, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_52P26 = 8, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_106P26 = 9, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_484P242 = 10, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_996P484 = 11, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_996P484P242 = 12, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_2x996P484 = 13, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_3x996 = 14, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE_3x996P484 = 15, -+ -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX = 0x00001fe0, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOCATION1 = 0x003fe000, -+ IEEE80211_RADIOTAP_EHT_DATA1_RU_PRIMARY_80MHZ_CHAN_POS = 0xc0000000, -+}; -+ -+enum ieee80211_radiotap_eht_data2_to_data6 { -+ IEEE80211_RADIOTAP_EHT_DATA2_6_RU_ALLOCATION_X = 0x000001ff, -+ IEEE80211_RADIOTAP_EHT_DATA2_6_RU_ALLOCATION_X_KNOWN = 0x00000200, -+ IEEE80211_RADIOTAP_EHT_DATA2_6_RU_ALLOCATION_XP1 = 0x0007fc00, -+ IEEE80211_RADIOTAP_EHT_DATA2_6_RU_ALLOCATION_XP1_KNOWN = 0x00080000, -+ IEEE80211_RADIOTAP_EHT_DATA2_6_RU_ALLOCATION_XP2 = 0x1ff00000, -+ IEEE80211_RADIOTAP_EHT_DATA2_6_RU_ALLOCATION_XP2_KNOWN = 0x20000000, -+}; -+ -+enum ieee80211_radiotap_eht_data7 { -+ IEEE80211_RADIOTAP_EHT_DATA7_CRC2 = 0x0000000f, -+ IEEE80211_RADIOTAP_EHT_DATA7_TAIL2 = 0x000003f0, -+ IEEE80211_RADIOTAP_EHT_DATA7_NSS = 0x0000f000, -+ IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED = 0x00010000, -+ IEEE80211_RADIOTAP_EHT_DATA7_NUM_NON_OFDMA_USERS = 0x000e0000, -+ IEEE80211_RADIOTAP_EHT_DATA7_USR_ENC_BLK_CRC = 0x00f00000, -+ IEEE80211_RADIOTAP_EHT_DATA7_USR_ENC_BLK_TAIL = 0x3f000000, -+}; -+ -+enum ieee80211_radiotap_eht_data8 { -+ IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOCATION_PS160 = 0x00000001, -+ IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOCATION_TB_FORMAT1 = 0x00000002, -+ IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOCATION_TB_FORMAT2 = 0x000001fc, -+}; -+ -+enum ieee80211_radiotap_eht_user_info { -+ IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN = 0x00000001, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN = 0x00000002, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN = 0x00000004, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_RSVD_KNOWN = 0x00000008, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN = 0x00000010, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN = 0x00000020, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN = 0x00000040, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_DATA_CAPTURE = 0x00000080, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID = 0x0007ff00, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_CODING = 0x00080000, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_MCS = 0x00f00000, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_NSS = 0x0f000000, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING = 0x20000000, -+ IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG = 0x3f000000, -+}; -+ -+struct ieee80211_radiotap_eht { -+ __le32 known; -+ __le32 data[9]; -+ __le32 user_info[]; -+}; -+ - /** - * ieee80211_get_radiotap_len - get radiotap header length - */ ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1441,7 +1441,11 @@ ieee80211_tx_info_clear_status(struct ie - * known the frame shouldn't be reported. - * @RX_FLAG_8023: the frame has an 802.3 header (decap offload performed by - * hardware or driver) -+ * @RX_FLAG_USIG_HEADER: Universal field carries information necessary to -+ * interpret EHT PPDUs. -+ * @RX_FLAG_EHT_HEADER: EHT radiotap data is present. - */ -+ - enum mac80211_rx_flags { - RX_FLAG_MMIC_ERROR = BIT(0), - RX_FLAG_DECRYPTED = BIT(1), -@@ -1473,6 +1477,8 @@ enum mac80211_rx_flags { - RX_FLAG_RADIOTAP_LSIG = BIT(27), - RX_FLAG_NO_PSDU = BIT(28), - RX_FLAG_8023 = BIT(29), -+ RX_FLAG_USIG_HEADER = BIT(30), -+ RX_FLAG_EHT_HEADER = BIT(31), - }; - - /** -@@ -1540,6 +1546,7 @@ enum mac80211_rx_encoding { - * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) - * @nss: number of streams (VHT, HE and EHT only) - * @flag: %RX_FLAG_\* -+ * @ext_flag: %RX_FLAG_\* - * @encoding: &enum mac80211_rx_encoding - * @bw: &enum rate_info_bw - * @enc_flags: uses bits from &enum mac80211_rx_encoding_flags -@@ -1593,6 +1600,7 @@ struct ieee80211_rx_status { - u8 ampdu_delimiter_crc; - u8 zero_length_psdu_type; - u8 link_valid:1, link_id:4; -+ u8 eht_num_user; - }; - - static inline u32 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -143,6 +143,12 @@ ieee80211_rx_radiotap_hdrlen(struct ieee - /* always present fields */ - len = sizeof(struct ieee80211_radiotap_header) + 8; - -+ /* EHT present fields */ -+ if ((status->flag & RX_FLAG_EHT_HEADER) || -+ (status->flag & RX_FLAG_USIG_HEADER)) { -+ len += 4; -+ } -+ - /* allocate extra bitmaps */ - if (status->chains) - len += 4 * hweight8(status->chains); -@@ -202,6 +208,20 @@ ieee80211_rx_radiotap_hdrlen(struct ieee - BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_lsig) != 4); - } - -+ if (status->flag & RX_FLAG_USIG_HEADER && -+ status->encoding == RX_ENC_EHT) { -+ len = ALIGN(len, 4); -+ len += 12; -+ BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_usig) != 12); -+ } -+ -+ if (status->flag & RX_FLAG_EHT_HEADER && -+ status->encoding == RX_ENC_EHT) { -+ len = ALIGN(len, 4); -+ len += 40; -+ len += status->eht_num_user * 4; -+ } -+ - if (status->chains) { - /* antenna and antenna signal fields */ - len += 2 * hweight8(status->chains); -@@ -223,6 +243,15 @@ ieee80211_rx_radiotap_hdrlen(struct ieee - if (status->flag & RX_FLAG_RADIOTAP_LSIG) - tlv_offset += - sizeof(struct ieee80211_radiotap_lsig); -+ if (status->flag & RX_FLAG_USIG_HEADER) -+ tlv_offset += -+ sizeof(struct ieee80211_radiotap_usig); -+ if (status->flag & RX_FLAG_EHT_HEADER) { -+ tlv_offset += -+ sizeof(struct ieee80211_radiotap_eht); -+ tlv_offset += -+ status->eht_num_user * sizeof(u32); -+ } - - /* ensure 4 byte alignment for TLV */ - len = ALIGN(len, 4); -@@ -330,6 +359,14 @@ ieee80211_add_rx_radiotap_header(struct - struct ieee80211_radiotap_he he = {}; - struct ieee80211_radiotap_he_mu he_mu = {}; - struct ieee80211_radiotap_lsig lsig = {}; -+ struct ieee80211_radiotap_usig usig = {}; -+ struct ieee80211_radiotap_eht eht = {}; -+ u32 *user_info; -+ bool rhdr_ext = false; -+ -+ if ((status->flag & RX_FLAG_USIG_HEADER) || -+ (status->flag & RX_FLAG_EHT_HEADER)) -+ rhdr_ext = true; - - if (status->flag & RX_FLAG_RADIOTAP_HE) { - he = *(struct ieee80211_radiotap_he *)skb->data; -@@ -352,6 +389,20 @@ ieee80211_add_rx_radiotap_header(struct - tlvs_len = skb_mac_header(skb) - skb->data; - } - -+ if (status->flag & RX_FLAG_USIG_HEADER) { -+ usig = *(struct ieee80211_radiotap_usig *)skb->data; -+ skb_pull(skb, sizeof(usig)); -+ WARN_ON_ONCE(status->encoding != RX_ENC_EHT); -+ } -+ -+ if (status->flag & RX_FLAG_EHT_HEADER) { -+ eht = *(struct ieee80211_radiotap_eht *)skb->data; -+ skb_pull(skb, sizeof(eht)); -+ user_info = (u32 *)skb->data; -+ skb_pull(skb, status->eht_num_user * sizeof(u32)); -+ WARN_ON_ONCE(status->encoding != RX_ENC_EHT); -+ } -+ - mpdulen = skb->len; - if (!(has_fcs && ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS))) - mpdulen += FCS_LEN; -@@ -382,6 +433,19 @@ ieee80211_add_rx_radiotap_header(struct - if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) - it_present_val |= BIT(IEEE80211_RADIOTAP_TLV); - -+ if (rhdr_ext) { -+ it_present_val |= BIT(IEEE80211_RADIOTAP_EXT); -+ put_unaligned_le32(it_present_val, it_present); -+ it_present_val = 0; -+ it_present++; -+ /* IEEE80211_RADIOTAP_USIG */ -+ if (status->flag & RX_FLAG_USIG_HEADER) -+ it_present_val |= BIT(IEEE80211_RADIOTAP_USIG_INFO); -+ /* IEEE80211_RADIOTAP_EHT */ -+ if (status->flag & RX_FLAG_EHT_HEADER) -+ it_present_val |= BIT(IEEE80211_RADIOTAP_EHT_INFO); -+ } -+ - put_unaligned_le32(it_present_val, it_present); - - /* This references through an offset into it_optional[] rather -@@ -706,6 +770,22 @@ ieee80211_add_rx_radiotap_header(struct - *pos++ = status->chain_signal[chain]; - *pos++ = chain; - } -+ -+ if (status->flag & RX_FLAG_USIG_HEADER) { -+ while ((pos - (u8 *)rthdr) & 1) -+ pos++; -+ memcpy(pos, &usig, sizeof(usig)); -+ pos += sizeof(usig); -+ } -+ -+ if (status->flag & RX_FLAG_EHT_HEADER) { -+ while ((pos - (u8 *)rthdr) & 1) -+ pos++; -+ memcpy(pos, &eht, sizeof(eht)); -+ pos += sizeof(eht); -+ memcpy(pos, user_info, (status->eht_num_user * sizeof(u32))); -+ pos += status->eht_num_user * sizeof(u32); -+ } - } - - static struct sk_buff * -@@ -800,6 +880,14 @@ ieee80211_rx_monitor(struct ieee80211_lo - if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) - rtap_space += skb_mac_header(origskb) - &origskb->data[rtap_space]; - -+ if (status->flag & RX_FLAG_USIG_HEADER) -+ rtap_space += sizeof(struct ieee80211_radiotap_usig); -+ -+ if (status->flag & RX_FLAG_EHT_HEADER) { -+ rtap_space += sizeof(struct ieee80211_radiotap_eht); -+ rtap_space += (status->eht_num_user * sizeof(u32)); -+ } -+ - min_head_len = rtap_space; - - /* diff --git a/package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch b/package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch deleted file mode 100644 index 4a8328f4e3..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/675-01-cfg80211-Extend-interface-combination-advertisement-.patch +++ /dev/null @@ -1,1594 +0,0 @@ -From 1c326ee47eb453b884aa0436916f73c458e1a7f3 Mon Sep 17 00:00:00 2001 -From: Vasanthakumar Thiagarajan -Date: Sat, 8 Oct 2022 13:59:17 +0530 -Subject: [PATCH 1/3] cfg80211/mac80211: extend iface comb -advertisement for multi-hardware dev - -When driver combines multiple discrete hardware under one wiphy, it is -required for the driver to be able to advertise iface combination -capabilities per underlying physical hardware. Iface combination for each -underlying hardware is described with an identifier, the same index which -is used in wiphy->hw_chans[] to learn the channel capabilities of the -respective hardware. It should be noted that the supporting drivers also -need to signal the iface comb capabilities that are common for all the -hardware through the existing interface to maintain the backward -compatibility with the user space. Provision to advertise per physical -hardware specific iface comb capabilities and the sanity checks on the -advertised capabilities are implemented in this commit. - -Example: - -Say driver abstracts two discrete hardware under one wiphy, -wiphy->hw_chans[0] supporting 2 GHz and wiphy->hw_chans[1] supporting -5 GHz. Each hardware can operate on only one channel at any given time -but under the wiphy there can be concurrent interfaces on both the radios. -2 GHz hardware supports #STA <= 1, #AP <= 3 total 4 and 5 GHz hardware -supports #STA <= 1, #AP <= 4 total 5 - -struct ieee80211_iface_limit limits_common[] = { - { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, - { .max = 3, .types = BIT(NL80211_IFTYPE_AP), }, -}; - -limits_common[] defines the minimum (common) capability out of all the -underlying hardware specific capabilities. This is reported in the existing -advertisement mechanism. Common max_interfaces across 2 GHz and 5 GHz is 4, -common num_different_channels is 1. - -struct ieee80211_iface_limit limits_2ghz[] = { - { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, - { .max = 3, .types = BIT(NL80211_IFTYPE_AP), }, -}; - -struct ieee80211_iface_limit limits_5ghz[] = { - { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, - { .max = 4, .types = BIT(NL80211_IFTYPE_AP), }, -}; - -struct ieee80211_iface_combination combination = { - .limits = limits_common, - .max_interfaces = 4, - .num_different_channels = 1, - ... - .freq_range = { - { - .hw_chan_idx = 0, - .limits = limits_2ghz, - .max_interfaces = 4, - .num_different_channels = 1, - .n_limits = ARRAY_SIZE(limits_2ghz), - }, - { - .hw_chan_idx = 1, - .limits = limits_5ghz, - .max_interfaces = 5, - .num_different_channels = 1, - .n_limits = ARRAY_SIZE(limits_5ghz), - }, - }, -}; - -Signed-off-by: Vasanthakumar Thiagarajan ---- - include/net/cfg80211.h | 188 +++++++++++++++++++- - net/mac80211/chan.c | 29 ++- - net/mac80211/ieee80211_i.h | 5 +- - net/mac80211/main.c | 58 ++++++ - net/mac80211/util.c | 315 ++++++++++++++++++++++++++------ - net/wireless/core.c | 265 ++++++++++++++++++++++----- - net/wireless/util.c | 356 +++++++++++++++++++++++++++++++++---- - 7 files changed, 1073 insertions(+), 143 deletions(-) - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -1537,27 +1537,60 @@ struct cfg80211_color_change_settings { - }; - - /** -+ * struct iface_comb_per_hw_params - HW specific interface combinations input -+ * -+ * Used to pass per-hw interface combination parameters -+ * -+ * @num_different_channels: the number of different channels we want to use -+ * with in the per-hw supported channels. -+ * @iftype_num: array with the number of interfaces of each interface -+ * type. The index is the interface type as specified in &enum -+ * nl80211_iftype. -+ */ -+ -+struct iface_comb_per_hw_params { -+ int num_different_channels; -+ int iftype_num[NUM_NL80211_IFTYPES]; -+}; -+ -+/** - * struct iface_combination_params - input parameters for interface combinations - * - * Used to pass interface combination parameters - * - * @num_different_channels: the number of different channels we want -- * to use for verification -+ * to use for verification, not applicable when hw specific interface -+ * combination parameters are passed in @per_hw_params - * @radar_detect: a bitmap where each bit corresponds to a channel - * width where radar detection is needed, as in the definition of - * &struct ieee80211_iface_combination.@radar_detect_widths - * @iftype_num: array with the number of interfaces of each interface - * type. The index is the interface type as specified in &enum -- * nl80211_iftype. -+ * nl80211_iftype. This will hold the interfaces which are not -+ * yet assigned a channel when hw specific interface combination -+ * is passed in @per_hw_params. - * @new_beacon_int: set this to the beacon interval of a new interface - * that's not operating yet, if such is to be checked as part of - * the verification -+ * @per_hw: underlying hw specific interface combinations. Per-hw channel -+ * list index as advertised in wiphy @hw_chans is used as index -+ * in @per_hw to maintain the interface combination of the corresponding -+ * hw. -+ * @chandef: Channel definition for which the interface combination is to be -+ * checked, when checking during interface preparation on a new channel, -+ * for example. This will be used when the driver advertises underlying -+ * hw specific interface combination in a multi-mac device. This will be -+ * NULL when the interface combination check is not due to channel or the -+ * interface combination does not include per-hw advertisement. -+ * - */ - struct iface_combination_params { - int num_different_channels; - u8 radar_detect; - int iftype_num[NUM_NL80211_IFTYPES]; - u32 new_beacon_int; -+ struct iface_comb_per_hw_params *per_hw; -+ const struct cfg80211_chan_def *chandef; - }; - - /** -@@ -4941,6 +4974,32 @@ struct ieee80211_iface_limit { - }; - - /** -+ * strucieee80211_iface_per_hw - hardware specific interface combination -+ * -+ * Drivers registering multiple radios under a single wiphy can advertise -+ * radio specific interface combinations through this structure. Please note -+ * that to maintain the compatibility with the user space which is not aware -+ * of this extension of per-hardware interface combination signaling, -+ * the driver should still advertise it's interface combination (mostly -+ * common minimum capability) using the existing interface combination signaling -+ * method. -+ * -+ * @hw_chans_idx: index of hardware specific channel list as per wiphy @hw_chans -+ * @limits: limits for the given interface type -+ * @num_different_channels: number of different channels which can be active -+ * concurrently in this hw -+ * @max_interfaces: maximum number of total interfaces allowed in this group -+ * @n_limits: number of limitations -+ */ -+struct ieee80211_iface_per_hw { -+ u8 hw_chans_idx; -+ const struct ieee80211_iface_limit *limits; -+ u32 num_different_channels; -+ u16 max_interfaces; -+ u8 n_limits; -+}; -+ -+/** - * struct ieee80211_iface_combination - possible interface combination - * - * With this structure the driver can describe which interface -@@ -4998,6 +5057,62 @@ struct ieee80211_iface_limit { - * .num_different_channels = 2, - * }; - * -+ * -+ * 4. Hardware specific interface combination with driver supporting two hw -+ * (MAC), one underlying MAC supporting 2 GHz band and the other supporting -+ * 5 GHz band. -+ * -+ * Allow #STA <= 1, #AP <= 1, channels = 1, total 2 in 2 GHz radio and -+ * -+ * Allow #STA <= 1, #AP <= 2, channels = 1, total 3 in 5 GHz radio -+ * -+ * Drivers advertising per-hardware interface combination should also -+ * advertise a sub-set of capabilities using existing interface mainly for -+ * maintaining compatibility with the user space which is not aware of the -+ * new per-hardware advertisement. -+ * -+ * Sub-set interface combination advertised in the existing infrastructure: -+ * Allow #STA <= 1, #AP <= 1, channel = 1, total 2 -+ * -+ * .. code-block:: c -+ * -+ * struct ieee80211_iface_limit limits4[] = { -+ * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, -+ * { .max = 1, .types = BIT(NL80211_IFTYPE_AP), }, -+ * }; -+ * struct ieee80211_iface_limit limits5_2ghz[] = { -+ * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, -+ * { .max = 1, .types = BIT(NL80211_IFTYPE_AP), }, -+ * }; -+ * struct ieee80211_iface_limit limits5_5ghz[] = { -+ * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, -+ * { .max = 2, .types = BIT(NL80211_IFTYPE_AP), }, -+ * }; -+ * struct ieee80211_iface_per_hw hw_combinations[] = { -+ * { -+ * .hw_chans_idx = 0, -+ * .limits = limits5_2ghz, -+ * .num_different_channels = 1, -+ * .max_interfaces = 2, -+ * .n_limits = ARRAY_SIZE(limits5_2ghz), -+ * }, -+ * { -+ * .hw_chans_idx = 1, -+ * .limits = limits5_5ghz, -+ * .num_different_channels = 1, -+ * .max_interfaces = 3, -+ * .n_limits = ARRAY_SIZE(limits5_5ghz), -+ * }, -+ * }; -+ * struct ieee80211_iface_combination combination4 = { -+ * .limits = limits4, -+ * .n_limits = ARRAY_SIZE(limits4), -+ * .max_interfaces = 2, -+ * .num_different_channels = 1, -+ * .iface_hw_list = hw_combinations, -+ * .n_hw_list = ARRAY_SIZE(hw_combinations), -+ * }; -+ * - */ - struct ieee80211_iface_combination { - /** -@@ -5055,6 +5170,20 @@ struct ieee80211_iface_combination { - * combination must be greater or equal to this value. - */ - u32 beacon_int_min_gcd; -+ -+ /** -+ * @iface_hw_list: -+ * This wiphy has multiple underlying radios, describe interface -+ * combination for each of them, valid only when the driver advertises -+ * multi-radio presence in wiphy @hw_chans. -+ */ -+ const struct ieee80211_iface_per_hw *iface_hw_list; -+ -+ /** -+ * @n_hw_list: -+ * number of hardware in @iface_hw_List -+ */ -+ u32 n_hw_list; - }; - - struct ieee80211_txrx_stypes { -@@ -5305,6 +5434,18 @@ struct wiphy_iftype_akm_suites { - #define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff - - /** -+ * struct ieee80211_supported_chans_per_hw - supported channels as per the -+ * underlying constituent hw configuration -+ * -+ * @n_chans: number of channels in @chans -+ * @chans: list of channels supported by the constituent hw -+ */ -+struct ieee80211_chans_per_hw { -+ int n_chans; -+ struct ieee80211_channel chans[]; -+}; -+ -+/** - * struct wiphy - wireless hardware description - * @mtx: mutex for the data (structures) of this device - * @reg_notifier: the driver's regulatory notification callback, -@@ -5520,6 +5661,13 @@ struct wiphy_iftype_akm_suites { - * A value of %CFG80211_HW_TIMESTAMP_ALL_PEERS indicates the driver - * supports enabling HW timestamping for all peers (i.e. no need to - * specify a mac address). -+ * @hw_chans: list of the channels supported by every constituent underlying hw. -+ * The drivers registering multiple radios under the a wiphy can advertise -+ * the list of channels supported by each hw in this list. Underlying hw -+ * specific channel list can be used while describing interface combination -+ * for each of the underlying hw. -+ * @num_hw: number of underlying hw for which the channels list are advertised -+ * in @hw_chans. - */ - struct wiphy { - struct mutex mtx; -@@ -5670,6 +5818,9 @@ struct wiphy { - - u16 hw_timestamp_max_peers; - -+ struct ieee80211_chans_per_hw **hw_chans; -+ int num_hw; -+ - char priv[] __aligned(NETDEV_ALIGN); - }; - -@@ -8956,9 +9107,32 @@ int cfg80211_check_combinations(struct w - int cfg80211_iter_combinations(struct wiphy *wiphy, - struct iface_combination_params *params, - void (*iter)(const struct ieee80211_iface_combination *c, -- void *data), -+ void *data, int hw_chan_idx), - void *data); - -+/** -+ * cfg80211_per_hw_iface_comb_advertised - if per-hw iface combination supported -+ * -+ * @wiphy: the wiphy -+ * -+ * This function is used to check underlying per-hw interface combination is -+ * advertised by the driver. -+ */ -+bool cfg80211_per_hw_iface_comb_advertised(struct wiphy *wiphy); -+ -+/** -+ * cfg80211_get_hw_idx_by_chan - get the hw index by the channel -+ * -+ * @wiphy: the wiphy -+ * @chandef: channel definition for which the supported hw index is -+ * required -+ * -+ * returns -1 in case the channel is not supported by any of the constituent -+ * hw -+ */ -+int cfg80211_get_hw_idx_by_chan(struct wiphy *wiphy, -+ const struct cfg80211_chan_def *chandef); -+ - /* - * cfg80211_stop_iface - trigger interface disconnection - * -@@ -9152,6 +9326,16 @@ bool cfg80211_iftype_allowed(struct wiph - void cfg80211_assoc_comeback(struct net_device *netdev, - const u8 *ap_addr, u32 timeout); - -+/** -+ * cfg80211_hw_chans_includes_dfs - check if per-hardware channel includes DFS -+ * @chans: hardware channel list -+ * -+ * Check if the given per-hardware list includes channels in DFS range. -+ * Please note the channel is checked against the entire range of DFS -+ * freq in 5 GHz irrespective of regulatory configurations. -+ */ -+bool cfg80211_hw_chans_includes_dfs(const struct ieee80211_chans_per_hw *chans); -+ - /* Logging, debugging and troubleshooting/diagnostic helpers. */ - - /* wiphy_printk helpers, similar to dev_printk */ ---- a/net/mac80211/chan.c -+++ b/net/mac80211/chan.c -@@ -47,26 +47,41 @@ int ieee80211_chanctx_refcount(struct ie - ieee80211_chanctx_num_reserved(local, ctx); - } - --static int ieee80211_num_chanctx(struct ieee80211_local *local) -+static int ieee80211_num_chanctx(struct ieee80211_local *local, -+ const struct cfg80211_chan_def *chandef) - { - struct ieee80211_chanctx *ctx; - int num = 0; -+ int hw_idx, ctx_idx; - - lockdep_assert_held(&local->chanctx_mtx); - -- list_for_each_entry(ctx, &local->chanctx_list, list) -- num++; -+ hw_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy, chandef); -+ -+ list_for_each_entry(ctx, &local->chanctx_list, list) { -+ if (hw_idx < 0) -+ num++; -+ else { -+ ctx_idx = -+ cfg80211_get_hw_idx_by_chan(local->hw.wiphy, -+ &ctx->conf.def); -+ if (ctx_idx == hw_idx) -+ num++; -+ } -+ } - - return num; - } - --static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local) -+static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local, -+ const struct cfg80211_chan_def *chandef) - { - lockdep_assert_held(&local->chanctx_mtx); -- return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local); -+ return ieee80211_num_chanctx(local, chandef) < -+ ieee80211_max_num_channels(local, chandef); - } - --static struct ieee80211_chanctx * -+struct ieee80211_chanctx * - ieee80211_link_get_chanctx(struct ieee80211_link_data *link) - { - struct ieee80211_local *local __maybe_unused = link->sdata->local; -@@ -1116,7 +1131,7 @@ int ieee80211_link_reserve_chanctx(struc - - new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode); - if (!new_ctx) { -- if (ieee80211_can_create_new_chanctx(local)) { -+ if (ieee80211_can_create_new_chanctx(local, chandef)) { - new_ctx = ieee80211_new_chanctx(local, chandef, mode); - if (IS_ERR(new_ctx)) - return PTR_ERR(new_ctx); ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -2573,6 +2573,8 @@ void ieee80211_link_copy_chanctx_to_vlan - bool clear); - int ieee80211_chanctx_refcount(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx); -+struct ieee80211_chanctx * -+ieee80211_link_get_chanctx(struct ieee80211_link_data *link); - - void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, - struct ieee80211_chanctx *chanctx); -@@ -2594,7 +2596,8 @@ int ieee80211_check_combinations(struct - const struct cfg80211_chan_def *chandef, - enum ieee80211_chanctx_mode chanmode, - u8 radar_detect); --int ieee80211_max_num_channels(struct ieee80211_local *local); -+int ieee80211_max_num_channels(struct ieee80211_local *local, -+ const struct cfg80211_chan_def *chandef); - void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, - struct ieee80211_chanctx *ctx); - ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -937,6 +937,45 @@ static int ieee80211_init_cipher_suites( - return 0; - } - -+static int -+ieee80211_check_per_hw_iface_comb(struct ieee80211_local *local, -+ const struct ieee80211_iface_combination *c) -+{ -+ int h, l; -+ u32 hw_idx_bm = 0; -+ -+ if (!local->use_chanctx) -+ return -EINVAL; -+ -+ for (h = 0; h < c->n_hw_list; h++) { -+ const struct ieee80211_iface_per_hw *hl; -+ const struct ieee80211_chans_per_hw *chans; -+ -+ hl = &c->iface_hw_list[h]; -+ -+ if (hl->hw_chans_idx >= local->hw.wiphy->num_hw) -+ return -EINVAL; -+ -+ chans = local->hw.wiphy->hw_chans[hl->hw_chans_idx]; -+ if (c->radar_detect_widths && -+ cfg80211_hw_chans_includes_dfs(chans) && -+ hl->num_different_channels > 1) -+ return -EINVAL; -+ -+ for (l = 0; l < hl->n_limits; l++) -+ if ((hl->limits[l].types & BIT(NL80211_IFTYPE_ADHOC)) && -+ hl->limits[l].max > 1) -+ return -EINVAL; -+ -+ if (hw_idx_bm & BIT(h)) -+ return -EINVAL; -+ -+ hw_idx_bm |= BIT(h); -+ } -+ -+ return 0; -+} -+ - int ieee80211_register_hw(struct ieee80211_hw *hw) - { - struct ieee80211_local *local = hw_to_local(hw); -@@ -1051,6 +1090,25 @@ int ieee80211_register_hw(struct ieee802 - } - } - -+ for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { -+ const struct ieee80211_iface_combination *comb; -+ -+ comb = &local->hw.wiphy->iface_combinations[i]; -+ -+ if (comb->n_hw_list && !local->hw.wiphy->num_hw) -+ return -EINVAL; -+ -+ if (!comb->n_hw_list) -+ continue; -+ -+ /* -+ * Run through similar validations on the per-hardware -+ * interface combinations, if advertised. -+ */ -+ if (ieee80211_check_per_hw_iface_comb(local, comb)) -+ return -EINVAL; -+ } -+ - /* Only HW csum features are currently compatible with mac80211 */ - if (WARN_ON(hw->netdev_features & ~MAC80211_SUPPORTED_FEATURES)) - return -EINVAL; ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -4818,16 +4818,174 @@ static u8 ieee80211_chanctx_radar_detect - return radar_detect; - } - -+static void -+ieee80211_prepare_iface_combination(struct ieee80211_sub_if_data *sdata, -+ const struct cfg80211_chan_def *chandef, -+ enum ieee80211_chanctx_mode chanmode, -+ struct iface_combination_params *params, -+ int *total) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_sub_if_data *sdata_iter; -+ enum nl80211_iftype iftype = sdata->wdev.iftype; -+ struct ieee80211_chanctx *ctx; -+ -+ lockdep_assert_held(&local->chanctx_mtx); -+ -+ if (chandef) -+ params->num_different_channels = 1; -+ -+ if (iftype != NL80211_IFTYPE_UNSPECIFIED) -+ params->iftype_num[iftype] = 1; -+ -+ list_for_each_entry(ctx, &local->chanctx_list, list) { -+ if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) -+ continue; -+ params->radar_detect |= -+ ieee80211_chanctx_radar_detect(local, ctx); -+ if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { -+ params->num_different_channels++; -+ continue; -+ } -+ if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && -+ cfg80211_chandef_compatible(chandef, -+ &ctx->conf.def)) -+ continue; -+ params->num_different_channels++; -+ } -+ -+ list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { -+ struct wireless_dev *wdev_iter; -+ -+ wdev_iter = &sdata_iter->wdev; -+ -+ if (sdata_iter == sdata || -+ !ieee80211_sdata_running(sdata_iter) || -+ cfg80211_iftype_allowed(local->hw.wiphy, -+ wdev_iter->iftype, 0, 1)) -+ continue; -+ -+ params->iftype_num[wdev_iter->iftype]++; -+ (*total)++; -+ } -+} -+ -+static void -+ieee80211_get_per_hw_sdata_active_iface(struct ieee80211_sub_if_data *sdata, -+ struct iface_combination_params *params, -+ int *total) -+{ -+ struct ieee80211_local *local = sdata->local; -+ unsigned int link_id; -+ int idx; -+ -+ for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) { -+ struct ieee80211_link_data *link; -+ struct ieee80211_chanctx *ctx; -+ -+ link = sdata_dereference(sdata->link[link_id], sdata); -+ if (!link) -+ continue; -+ -+ ctx = ieee80211_link_get_chanctx(link); -+ if (ctx && -+ ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) -+ ctx = ctx->replace_ctx; -+ -+ idx = -1; -+ if (ctx) -+ idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy, -+ &ctx->conf.def); -+ -+ if (idx >= 0) -+ params->per_hw[idx].iftype_num[sdata->wdev.iftype]++; -+ else -+ params->iftype_num[sdata->wdev.iftype]++; -+ -+ if (total) -+ (*total)++; -+ } -+} -+ -+static int -+ieee80211_prepare_per_hw_iface_combination(struct ieee80211_sub_if_data *sdata, -+ const struct cfg80211_chan_def *chandef, -+ enum ieee80211_chanctx_mode chanmode, -+ struct iface_combination_params *params, -+ int *total) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_sub_if_data *sdata_iter; -+ enum nl80211_iftype iftype = sdata->wdev.iftype; -+ struct ieee80211_chanctx *ctx; -+ int hchan_idx; -+ size_t size; -+ bool sdata_included = false; -+ -+ lockdep_assert_held(&local->chanctx_mtx); -+ -+ size = sizeof(*params->per_hw) * local->hw.wiphy->num_hw; -+ /* caller should free this memory upon success status */ -+ params->per_hw = kzalloc(size, GFP_KERNEL); -+ if (!params->per_hw) -+ return -ENOMEM; -+ -+ hchan_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy, chandef); -+ if (hchan_idx >= 0) { -+ params->per_hw[hchan_idx].num_different_channels = 1; -+ if (iftype != NL80211_IFTYPE_UNSPECIFIED) { -+ params->per_hw[hchan_idx].iftype_num[iftype] = 1; -+ sdata_included = true; -+ } -+ } -+ -+ list_for_each_entry(ctx, &local->chanctx_list, list) { -+ if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) -+ continue; -+ hchan_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy, -+ &ctx->conf.def); -+ if (WARN_ON(hchan_idx < 0)) -+ continue; -+ -+ params->radar_detect |= -+ ieee80211_chanctx_radar_detect(local, ctx); -+ if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { -+ params->per_hw[hchan_idx].num_different_channels++; -+ continue; -+ } -+ if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && -+ cfg80211_chandef_compatible(chandef, -+ &ctx->conf.def)) -+ continue; -+ params->per_hw[hchan_idx].num_different_channels++; -+ } -+ -+ list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { -+ struct wireless_dev *wdev_iter; -+ -+ wdev_iter = &sdata_iter->wdev; -+ -+ if ((sdata_included && sdata_iter == sdata) || -+ !ieee80211_sdata_running(sdata_iter) || -+ cfg80211_iftype_allowed(local->hw.wiphy, -+ wdev_iter->iftype, 0, 1)) -+ continue; -+ -+ ieee80211_get_per_hw_sdata_active_iface(sdata_iter, params, -+ total); -+ } -+ -+ return 0; -+} -+ - int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, - const struct cfg80211_chan_def *chandef, - enum ieee80211_chanctx_mode chanmode, - u8 radar_detect) - { - struct ieee80211_local *local = sdata->local; -- struct ieee80211_sub_if_data *sdata_iter; - enum nl80211_iftype iftype = sdata->wdev.iftype; -- struct ieee80211_chanctx *ctx; -- int total = 1; -+ int total = 1, ret; - struct iface_combination_params params = { - .radar_detect = radar_detect, - }; -@@ -4861,60 +5019,118 @@ int ieee80211_check_combinations(struct - return 0; - } - -- if (chandef) -- params.num_different_channels = 1; -+ if (cfg80211_per_hw_iface_comb_advertised(local->hw.wiphy)) { -+ ret = ieee80211_prepare_per_hw_iface_combination(sdata, chandef, -+ chanmode, -+ ¶ms, -+ &total); -+ if (ret) -+ return ret; -+ } else { -+ ieee80211_prepare_iface_combination(sdata, chandef, chanmode, -+ ¶ms, &total); -+ } - -- if (iftype != NL80211_IFTYPE_UNSPECIFIED) -- params.iftype_num[iftype] = 1; -+ if (total == 1 && !params.radar_detect) { -+ kfree(params.per_hw); -+ return 0; -+ } - -- list_for_each_entry(ctx, &local->chanctx_list, list) { -- if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) -- continue; -- params.radar_detect |= -- ieee80211_chanctx_radar_detect(local, ctx); -- if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { -- params.num_different_channels++; -+ ret = cfg80211_check_combinations(local->hw.wiphy, ¶ms); -+ -+ kfree(params.per_hw); -+ -+ return ret; -+} -+ -+static void -+ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c, -+ void *data, int hw_chan_idx) -+{ -+ u32 *max_num_different_channels = data; -+ -+ *max_num_different_channels = -+ max(*max_num_different_channels, c->num_different_channels); -+} -+ -+static void -+ieee80211_iter_per_hw_max_chans(const struct ieee80211_iface_combination *c, -+ void *data, int hw_chan_idx) -+{ -+ u32 *max_num_different_channels = data; -+ u32 max_supported_different_channels = 0; -+ int i; -+ -+ for (i = 0; i < c->n_hw_list; i++) { -+ const struct ieee80211_iface_per_hw *h; -+ -+ h = &c->iface_hw_list[i]; -+ if (hw_chan_idx != -1) { -+ if (h->hw_chans_idx == hw_chan_idx) { -+ max_supported_different_channels = -+ h->num_different_channels; -+ break; -+ } - continue; - } -- if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && -- cfg80211_chandef_compatible(chandef, -- &ctx->conf.def)) -- continue; -- params.num_different_channels++; -+ max_supported_different_channels += h->num_different_channels; - } - -- list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { -- struct wireless_dev *wdev_iter; -+ *max_num_different_channels = max(*max_num_different_channels, -+ max_supported_different_channels); -+} - -- wdev_iter = &sdata_iter->wdev; -+static int -+ieee80211_max_num_channels_hw_list(struct ieee80211_local *local, -+ const struct cfg80211_chan_def *chandef) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_chanctx *ctx; -+ u32 max_num_different_channels = 1; -+ size_t size; -+ int err, hchan_idx; -+ struct iface_combination_params params = { 0 }; -+ -+ size = sizeof(*params.per_hw) * local->hw.wiphy->num_hw; -+ /* caller should free this memory */ -+ params.per_hw = kzalloc(size, GFP_KERNEL); -+ if (!params.per_hw) -+ return -ENOMEM; - -- if (sdata_iter == sdata || -- !ieee80211_sdata_running(sdata_iter) || -- cfg80211_iftype_allowed(local->hw.wiphy, -- wdev_iter->iftype, 0, 1)) -+ params.chandef = chandef; -+ list_for_each_entry(ctx, &local->chanctx_list, list) { -+ if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) -+ continue; -+ hchan_idx = cfg80211_get_hw_idx_by_chan(local->hw.wiphy, -+ &ctx->conf.def); -+ if (WARN_ON(hchan_idx < 0)) - continue; - -- params.iftype_num[wdev_iter->iftype]++; -- total++; -+ params.radar_detect |= -+ ieee80211_chanctx_radar_detect(local, ctx); -+ params.per_hw[hchan_idx].num_different_channels++; - } - -- if (total == 1 && !params.radar_detect) -- return 0; -+ list_for_each_entry_rcu(sdata, &local->interfaces, list) { -+ struct wireless_dev *wdev = &sdata->wdev; - -- return cfg80211_check_combinations(local->hw.wiphy, ¶ms); --} -+ if (!ieee80211_sdata_running(sdata) || -+ cfg80211_iftype_allowed(local->hw.wiphy, wdev->iftype, 0, -+ 1)) -+ continue; -+ ieee80211_get_per_hw_sdata_active_iface(sdata, ¶ms, NULL); -+ } - --static void --ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c, -- void *data) --{ -- u32 *max_num_different_channels = data; -+ err = cfg80211_iter_combinations(local->hw.wiphy, ¶ms, -+ ieee80211_iter_per_hw_max_chans, -+ &max_num_different_channels); -+ kfree(params.per_hw); - -- *max_num_different_channels = max(*max_num_different_channels, -- c->num_different_channels); -+ return err < 0 ? err : max_num_different_channels; - } - --int ieee80211_max_num_channels(struct ieee80211_local *local) -+int ieee80211_max_num_channels(struct ieee80211_local *local, -+ const struct cfg80211_chan_def *chandef) - { - struct ieee80211_sub_if_data *sdata; - struct ieee80211_chanctx *ctx; -@@ -4924,6 +5140,9 @@ int ieee80211_max_num_channels(struct ie - - lockdep_assert_held(&local->chanctx_mtx); - -+ if (cfg80211_per_hw_iface_comb_advertised(local->hw.wiphy)) -+ return ieee80211_max_num_channels_hw_list(local, chandef); -+ - list_for_each_entry(ctx, &local->chanctx_list, list) { - if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) - continue; ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -594,10 +594,125 @@ use_default_name: - } - EXPORT_SYMBOL(wiphy_new_nm); - -+static int -+wiphy_verify_comb_limit(struct wiphy *wiphy, -+ const struct ieee80211_iface_limit *limits, -+ u8 n_limits, u32 bcn_int_min_gcd, u32 *iface_cnt, -+ u16 *all_iftypes) -+{ -+ int l; -+ -+ for (l = 0; l < n_limits; l++) { -+ u16 types = limits[l].types; -+ -+ /* -+ * Don't advertise an unsupported type -+ * in a combination. -+ */ -+ if (WARN_ON((wiphy->interface_modes & types) != types)) -+ return -EINVAL; -+ -+ /* interface types shouldn't overlap */ -+ if (WARN_ON(types & *all_iftypes)) -+ return -EINVAL; -+ -+ *all_iftypes |= types; -+ -+ /* Shouldn't list software iftypes in combinations! */ -+ if (WARN_ON(wiphy->software_iftypes & types)) -+ return -EINVAL; -+ -+ /* Only a single P2P_DEVICE can be allowed */ -+ if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && -+ limits[l].max > 1)) -+ return -EINVAL; -+ -+ /* Only a single NAN can be allowed */ -+ if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && -+ limits[l].max > 1)) -+ return -EINVAL; -+ -+ /* -+ * This isn't well-defined right now. If you have an -+ * IBSS interface, then its beacon interval may change -+ * by joining other networks, and nothing prevents it -+ * from doing that. -+ * So technically we probably shouldn't even allow AP -+ * and IBSS in the same interface, but it seems that -+ * some drivers support that, possibly only with fixed -+ * beacon intervals for IBSS. -+ */ -+ if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) && -+ bcn_int_min_gcd)) -+ return -EINVAL; -+ -+ *iface_cnt += limits[l].max; -+ } -+ -+ return 0; -+} -+ -+static int -+wiphy_verify_comb_per_hw(struct wiphy *wiphy, -+ const struct ieee80211_iface_combination *comb) -+{ -+ int h; -+ u32 hw_idx_bitmap = 0; -+ int ret; -+ -+ for (h = 0; h < comb->n_hw_list; h++) { -+ const struct ieee80211_iface_per_hw *hl; -+ const struct ieee80211_chans_per_hw *chans; -+ u32 iface_cnt = 0; -+ u16 all_iftypes = 0; -+ -+ hl = &comb->iface_hw_list[h]; -+ -+ if (hl->hw_chans_idx >= wiphy->num_hw) -+ return -EINVAL; -+ -+ if (hw_idx_bitmap & BIT(hl->hw_chans_idx)) -+ return -EINVAL; -+ -+ hw_idx_bitmap |= BIT(hl->hw_chans_idx); -+ chans = wiphy->hw_chans[hl->hw_chans_idx]; -+ -+ if (WARN_ON(hl->max_interfaces < 2 && (!comb->radar_detect_widths || -+ !(cfg80211_hw_chans_includes_dfs(chans))))) -+ return -EINVAL; -+ -+ if (WARN_ON(!hl->num_different_channels)) -+ return -EINVAL; -+ -+ if (WARN_ON(comb->radar_detect_widths && -+ cfg80211_hw_chans_includes_dfs(chans) && -+ hl->num_different_channels > 1)) -+ return -EINVAL; -+ -+ if (WARN_ON(!hl->n_limits)) -+ return -EINVAL; -+ -+ ret = wiphy_verify_comb_limit(wiphy, hl->limits, hl->n_limits, -+ comb->beacon_int_min_gcd, -+ &iface_cnt, &all_iftypes); -+ if (ret) -+ return ret; -+ -+ if (WARN_ON(all_iftypes & BIT(NL80211_IFTYPE_WDS))) -+ return -EINVAL; -+ -+ if (WARN_ON(iface_cnt < comb->max_interfaces)) -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ - static int wiphy_verify_combinations(struct wiphy *wiphy) - { - const struct ieee80211_iface_combination *c; -- int i, j; -+ int i; -+ int ret; - - for (i = 0; i < wiphy->n_iface_combinations; i++) { - u32 cnt = 0; -@@ -624,39 +739,11 @@ static int wiphy_verify_combinations(str - if (WARN_ON(!c->n_limits)) - return -EINVAL; - -- for (j = 0; j < c->n_limits; j++) { -- u16 types = c->limits[j].types; -- -- /* interface types shouldn't overlap */ -- if (WARN_ON(types & all_iftypes)) -- return -EINVAL; -- all_iftypes |= types; -- -- if (WARN_ON(!c->limits[j].max)) -- return -EINVAL; -- -- /* Shouldn't list software iftypes in combinations! */ -- if (WARN_ON(wiphy->software_iftypes & types)) -- return -EINVAL; -- -- /* Only a single P2P_DEVICE can be allowed */ -- if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) && -- c->limits[j].max > 1)) -- return -EINVAL; -- -- /* Only a single NAN can be allowed */ -- if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && -- c->limits[j].max > 1)) -- return -EINVAL; -- -- cnt += c->limits[j].max; -- /* -- * Don't advertise an unsupported type -- * in a combination. -- */ -- if (WARN_ON((wiphy->interface_modes & types) != types)) -- return -EINVAL; -- } -+ ret = wiphy_verify_comb_limit(wiphy, c->limits, c->n_limits, -+ c->beacon_int_min_gcd, -+ &cnt, &all_iftypes); -+ if (ret) -+ return ret; - - if (WARN_ON(all_iftypes & BIT(NL80211_IFTYPE_WDS))) - return -EINVAL; -@@ -664,11 +751,119 @@ static int wiphy_verify_combinations(str - /* You can't even choose that many! */ - if (WARN_ON(cnt < c->max_interfaces)) - return -EINVAL; -+ /* -+ * Do similar validations on the freq range specific interface -+ * combinations when advertised. -+ */ -+ if (WARN_ON(c->n_hw_list && -+ wiphy_verify_comb_per_hw(wiphy, c))) -+ return -EINVAL; - } - - return 0; - } - -+static int cfg80211_check_hw_chans(const struct ieee80211_chans_per_hw *chans1, -+ const struct ieee80211_chans_per_hw *chans2) -+{ -+ int i, j; -+ -+ if (!chans1 || !chans2) -+ return -EINVAL; -+ -+ if (!chans1->n_chans || !chans2->n_chans) -+ return -EINVAL; -+ -+ /* for now same channel is not allowed in more than one sub-hw */ -+ for (i = 0; i < chans1->n_chans; i++) -+ for (j = 0; j < chans2->n_chans; j++) -+ if (chans1->chans[i].center_freq == -+ chans2->chans[j].center_freq) -+ return -EINVAL; -+ return 0; -+} -+ -+static bool -+cfg80211_hw_chans_in_supported_list(struct wiphy *wiphy, -+ const struct ieee80211_chans_per_hw *chans) -+{ -+ enum nl80211_band band; -+ struct ieee80211_supported_band *sband; -+ bool found; -+ int i, j; -+ -+ for (i = 0; i < chans->n_chans; i++) { -+ found = false; -+ for (band = 0; band < NUM_NL80211_BANDS; band++) { -+ sband = wiphy->bands[band]; -+ if (!sband) -+ continue; -+ for (j = 0; j < sband->n_channels; j++) { -+ if (chans->chans[i].center_freq == -+ sband->channels[j].center_freq) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (found) -+ break; -+ } -+ -+ if (!found) -+ return false; -+ } -+ -+ return true; -+} -+ -+static int cfg80211_validate_per_hw_chans(struct wiphy *wiphy) -+{ -+ int i, j; -+ int ret; -+ -+ if (!wiphy->num_hw) -+ return 0; -+ -+ if (!wiphy->hw_chans) -+ return -EINVAL; -+ -+ /* -+ * to advertise channel list for one hw, sband alone should -+ * be sufficient -+ */ -+ if (wiphy->num_hw < 2) -+ return -EINVAL; -+ -+ for (i = 0; i < wiphy->num_hw; i++) { -+ for (j = 0; j < wiphy->num_hw; j++) { -+ const struct ieee80211_chans_per_hw *hw_chans1; -+ const struct ieee80211_chans_per_hw *hw_chans2; -+ -+ if (i == j) -+ continue; -+ -+ hw_chans1 = wiphy->hw_chans[i]; -+ hw_chans2 = wiphy->hw_chans[j]; -+ ret = cfg80211_check_hw_chans(hw_chans1, hw_chans2); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ for (i = 0; i < wiphy->num_hw; i++) { -+ const struct ieee80211_chans_per_hw *hw_chans; -+ -+ hw_chans = wiphy->hw_chans[i]; -+ if (!cfg80211_hw_chans_in_supported_list(wiphy, hw_chans)) { -+ WARN_ON(1); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ - int wiphy_register(struct wiphy *wiphy) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -@@ -905,6 +1100,11 @@ int wiphy_register(struct wiphy *wiphy) - WARN_ON(1); - return -EINVAL; - } -+ -+ if (cfg80211_validate_per_hw_chans(&rdev->wiphy)) { -+ WARN_ON(1); -+ return -EINVAL; -+ } - - for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) { - /* ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -2204,19 +2204,271 @@ int cfg80211_validate_beacon_int(struct - return 0; - } - -+static const struct ieee80211_iface_per_hw * -+cfg80211_get_hw_iface_comb_by_idx(struct wiphy *wiphy, -+ const struct ieee80211_iface_combination *c, -+ int idx) -+{ -+ int i; -+ -+ for (i = 0; i < c->n_hw_list; i++) -+ if (c->iface_hw_list[i].hw_chans_idx == idx) -+ break; -+ -+ if (i == c->n_hw_list) -+ return NULL; -+ -+ return &c->iface_hw_list[i]; -+} -+ -+static int -+cfg80211_validate_per_hw_iface_comb_limits(struct wiphy *wiphy, -+ struct iface_combination_params *params, -+ const struct ieee80211_iface_combination *c, -+ int *num_per_hw_ifaces, u32 *all_iftypes) -+{ -+ struct ieee80211_iface_limit **limits; -+ const struct ieee80211_iface_per_hw *per_hw_comb; -+ int iftype_num[NUM_NL80211_IFTYPES] = { 0 }; -+ int *n_limits; -+ int ret = 0; -+ int i, j, iftype; -+ -+ limits = kzalloc(sizeof(*limits) * wiphy->num_hw, GFP_KERNEL); -+ if (!limits) -+ return -ENOMEM; -+ -+ n_limits = kzalloc(sizeof(*n_limits) * wiphy->num_hw, GFP_KERNEL); -+ if (!n_limits) { -+ kfree(limits); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < wiphy->num_hw; i++) { -+ per_hw_comb = cfg80211_get_hw_iface_comb_by_idx(wiphy, c, i); -+ if (!per_hw_comb) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ -+ limits[i] = kmemdup(per_hw_comb->limits, -+ per_hw_comb->n_limits * -+ sizeof(limits[i][0]), GFP_KERNEL); -+ if (!limits[i]) { -+ ret = -ENOMEM; -+ goto out_free; -+ } -+ -+ n_limits[i] = per_hw_comb->n_limits; -+ } -+ -+ for (i = 0; i < wiphy->num_hw; i++) { -+ per_hw_comb = cfg80211_get_hw_iface_comb_by_idx(wiphy, c, i); -+ if (!per_hw_comb) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ -+ if (num_per_hw_ifaces[i] > per_hw_comb->max_interfaces) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ -+ if (params->per_hw[i].num_different_channels > -+ per_hw_comb->num_different_channels) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ -+ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { -+ if (cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) -+ continue; -+ for (j = 0; j < n_limits[i]; j++) { -+ *all_iftypes |= limits[i][j].types; -+ if (!(limits[i][j].types & BIT(iftype))) -+ continue; -+ if (limits[i][j].max < -+ params->per_hw[i].iftype_num[iftype]) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ -+ limits[i][j].max -= -+ params->per_hw[i].iftype_num[iftype]; -+ } -+ } -+ } -+ -+ memcpy(iftype_num, params->iftype_num, NUM_NL80211_IFTYPES); -+ for (i = 0; i < wiphy->num_hw; i++) { -+ u16 rem_iface; -+ per_hw_comb = cfg80211_get_hw_iface_comb_by_idx(wiphy, c, i); -+ if (!per_hw_comb) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ -+ /* -+ * we'll not be here in the first place if the numbre of per-hw -+ * interfaces are more than the advertised ones. So it is safe -+ * to ignore that error case here. -+ */ -+ rem_iface = per_hw_comb->max_interfaces - num_per_hw_ifaces[i]; -+ if (!rem_iface) -+ continue; -+ -+ /* -+ * check if the interfaces which are not yet assigned the -+ * operating channel can be accommodated with all the available -+ * per-hw interface combination advertisements. -+ */ -+ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { -+ if (cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) -+ continue; -+ if (!rem_iface) -+ break; -+ for (j = 0; j < n_limits[i]; j++) { -+ u16 num_avail; -+ if (!(limits[i][j].types & BIT(iftype))) -+ continue; -+ if (!rem_iface) -+ break; -+ num_avail = min(rem_iface, limits[i][j].max); -+ if (num_avail < iftype_num[iftype]) { -+ iftype_num[iftype] -= num_avail; -+ rem_iface -= num_avail; -+ } else { -+ rem_iface -= iftype_num[iftype]; -+ iftype_num[iftype] = 0; -+ } -+ } -+ } -+ } -+ -+ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { -+ if (iftype_num[iftype]) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ } -+ -+out_free: -+ for (i = 0; i < wiphy->num_hw; i++) -+ kfree(limits[i]); -+ -+ kfree(n_limits); -+ kfree(limits); -+ -+ return ret; -+} -+ -+static int -+cfg80211_validate_iface_comb_limits(struct wiphy *wiphy, -+ struct iface_combination_params *params, -+ const struct ieee80211_iface_combination *c, -+ int num_interfaces, u32 *all_iftypes) -+{ -+ struct ieee80211_iface_limit *limits; -+ int j, iftype; -+ int ret = 0; -+ -+ if (num_interfaces > c->max_interfaces) -+ return -EINVAL; -+ if (params->num_different_channels > c->num_different_channels) -+ return -EINVAL; -+ -+ limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, -+ GFP_KERNEL); -+ if (!limits) -+ return -ENOMEM; -+ -+ for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { -+ if (cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) -+ continue; -+ for (j = 0; j < c->n_limits; j++) { -+ *all_iftypes |= limits[j].types; -+ if (!(limits[j].types & BIT(iftype))) -+ continue; -+ if (limits[j].max < params->iftype_num[iftype]) { -+ ret = -EINVAL; -+ goto out_free; -+ } -+ limits[j].max -= params->iftype_num[iftype]; -+ } -+ } -+out_free: -+ kfree(limits); -+ return ret; -+} -+ -+bool cfg80211_per_hw_iface_comb_advertised(struct wiphy *wiphy) -+{ -+ int i; -+ -+ for (i = 0; i < wiphy->n_iface_combinations; i++) { -+ const struct ieee80211_iface_combination *c; -+ c = &wiphy->iface_combinations[i]; -+ if (c->n_hw_list) -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(cfg80211_per_hw_iface_comb_advertised); -+ -+static bool -+cfg80211_chan_supported_by_sub_hw(struct ieee80211_chans_per_hw *hw_chans, -+ const struct cfg80211_chan_def *chandef) -+{ -+ int i; -+ -+ for (i = 0; i < hw_chans->n_chans; i++) -+ if (chandef->chan->center_freq == -+ hw_chans->chans[i].center_freq) -+ return true; -+ -+ return false; -+} -+ -+int -+cfg80211_get_hw_idx_by_chan(struct wiphy *wiphy, -+ const struct cfg80211_chan_def *chandef) -+{ -+ int i; -+ -+ if (!chandef) -+ return -1; -+ -+ if (!cfg80211_chandef_valid(chandef)) -+ return -1; -+ -+ for (i = 0; i < wiphy->num_hw; i++) { -+ if (cfg80211_chan_supported_by_sub_hw(wiphy->hw_chans[i], -+ chandef)) -+ return i; -+ } -+ -+ return -1; -+} -+EXPORT_SYMBOL(cfg80211_get_hw_idx_by_chan); -+ - int cfg80211_iter_combinations(struct wiphy *wiphy, - struct iface_combination_params *params, - void (*iter)(const struct ieee80211_iface_combination *c, -- void *data), -+ void *data, int hw_chan_idx), - void *data) - { - const struct ieee80211_regdomain *regdom; - enum nl80211_dfs_regions region = 0; -- int i, j, iftype; -+ int i, iftype; - int num_interfaces = 0; -+ int *num_per_hw_ifaces = NULL; - u32 used_iftypes = 0; - u32 beacon_int_gcd; - bool beacon_int_different; -+ bool per_hw_iface_comb_used; -+ int hw_chan_idx = -1; -+ int ret = 0; - - /* - * This is a bit strange, since the iteration used to rely only on -@@ -2239,50 +2491,66 @@ int cfg80211_iter_combinations(struct wi - rcu_read_unlock(); - } - -+ per_hw_iface_comb_used = cfg80211_per_hw_iface_comb_advertised(wiphy); -+ if (per_hw_iface_comb_used) { -+ num_per_hw_ifaces = kzalloc(sizeof(*num_per_hw_ifaces) * -+ wiphy->num_hw, GFP_KERNEL); -+ if (!num_per_hw_ifaces) -+ return -ENOMEM; -+ -+ hw_chan_idx = cfg80211_get_hw_idx_by_chan(wiphy, -+ params->chandef); -+ } -+ - for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { - num_interfaces += params->iftype_num[iftype]; - if (params->iftype_num[iftype] > 0 && - !cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) - used_iftypes |= BIT(iftype); -+ -+ if (!per_hw_iface_comb_used) -+ continue; -+ -+ /* account per_hw interfaces, if advertised */ -+ for (i = 0; i < wiphy->num_hw; i++) { -+ struct iface_comb_per_hw_params *per_hw; -+ per_hw = ¶ms->per_hw[i]; -+ num_per_hw_ifaces[i] += per_hw->iftype_num[iftype]; -+ if (per_hw->iftype_num[iftype] > 0 && -+ !cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) -+ used_iftypes |= BIT(iftype); -+ } - } - - for (i = 0; i < wiphy->n_iface_combinations; i++) { - const struct ieee80211_iface_combination *c; -- struct ieee80211_iface_limit *limits; - u32 all_iftypes = 0; - - c = &wiphy->iface_combinations[i]; - -- if (num_interfaces > c->max_interfaces) -- continue; -- if (params->num_different_channels > c->num_different_channels) -- continue; -+ if (per_hw_iface_comb_used) -+ ret = cfg80211_validate_per_hw_iface_comb_limits(wiphy, -+ params, c, -+ num_per_hw_ifaces, -+ &all_iftypes); -+ else -+ ret = cfg80211_validate_iface_comb_limits(wiphy, params, -+ c, -+ num_interfaces, -+ &all_iftypes); -+ if (ret == -ENOMEM) -+ goto out_free; - -- limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, -- GFP_KERNEL); -- if (!limits) -- return -ENOMEM; -- -- for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { -- if (cfg80211_iftype_allowed(wiphy, iftype, 0, 1)) -- continue; -- for (j = 0; j < c->n_limits; j++) { -- all_iftypes |= limits[j].types; -- if (!(limits[j].types & BIT(iftype))) -- continue; -- if (limits[j].max < params->iftype_num[iftype]) -- goto cont; -- limits[j].max -= params->iftype_num[iftype]; -- } -- } -+ if (ret) -+ continue; - - if (params->radar_detect != -- (c->radar_detect_widths & params->radar_detect)) -- goto cont; -+ (c->radar_detect_widths & params->radar_detect)) -+ continue; - - if (params->radar_detect && c->radar_detect_regions && - !(c->radar_detect_regions & BIT(region))) -- goto cont; -+ continue; - - /* Finally check that all iftypes that we're currently - * using are actually part of this combination. If they -@@ -2290,32 +2558,32 @@ int cfg80211_iter_combinations(struct wi - * to continue to the next. - */ - if ((all_iftypes & used_iftypes) != used_iftypes) -- goto cont; -+ continue; - - if (beacon_int_gcd) { - if (c->beacon_int_min_gcd && - beacon_int_gcd < c->beacon_int_min_gcd) -- goto cont; -+ continue; - if (!c->beacon_int_min_gcd && beacon_int_different) -- goto cont; -+ continue; - } - - /* This combination covered all interface types and - * supported the requested numbers, so we're good. - */ - -- (*iter)(c, data); -- cont: -- kfree(limits); -+ (*iter)(c, data, hw_chan_idx); - } - -- return 0; -+out_free: -+ kfree(num_per_hw_ifaces); -+ return ret; - } - EXPORT_SYMBOL(cfg80211_iter_combinations); - - static void - cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c, -- void *data) -+ void *data, int hw_chan_idx) - { - int *num = data; - (*num)++; -@@ -2709,3 +2977,21 @@ cfg80211_get_iftype_ext_capa(struct wiph - return NULL; - } - EXPORT_SYMBOL(cfg80211_get_iftype_ext_capa); -+ -+bool -+cfg80211_hw_chans_includes_dfs(const struct ieee80211_chans_per_hw *chans) -+{ -+ int i; -+ -+ for (i = 0; i < chans->n_chans; i++) { -+ if (chans->chans[i].band == NL80211_BAND_5GHZ && -+ ((chans->chans[i].center_freq >= 5250 && -+ chans->chans[i].center_freq <= 5340) || -+ (chans->chans[i].center_freq >= 5480 && -+ chans->chans[i].center_freq <= 5720))) -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(cfg80211_hw_chans_includes_dfs); diff --git a/package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch b/package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch deleted file mode 100644 index 1bfa9b89b4..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/702-ath11k-fix-memory-leak-in-dp-rx.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 9e4857cfe7f646c239fde030eb16b3d6520c34d8 Mon Sep 17 00:00:00 2001 -From: Hari Chandrakanthan -Date: Fri, 6 Jan 2023 12:49:44 +0530 -Subject: [PATCH] ath11k: fix memory leak in dp rx - -In dp rx path, by default, fast_rx is set as true. -And if peer supports fast rx, the frame is sent to upper layer -through napi_gro_receive. - -If peer doesn't support fast rx, the frames need to be processed in -ath11k_dp_rx_deliver_msdu and sent to mac80211 using ieee80211_rx_napi. -In dp rx path, the api ath11k_dp_rx_h_mpdu checks whether peer supports -fast rx. - -If peer find fails in ath11k_dp_rx_h_mpdu, the skb is not sent to network stack -as well as mac80211. Because the argument fast_rx is not set to false in ath11k_dp_rx_h_mpdu -when peer find fails. - -This can lead to memory leak. - -Fix it by setting argument fast_rx as false in ath11k_dp_rx_h_mpdu -so that the skb is sent to mac80211 through ath11k_dp_rx_deliver_msdu. - -Signed-off-by: Hari Chandrakanthan ---- - drivers/net/wireless/ath/ath11k/dp_rx.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2512,8 +2512,6 @@ static void ath11k_dp_rx_h_mpdu(struct a - } - } - -- *fast_rx = false; -- - if (rxcb->is_mcbc) - enctype = peer->sec_type_grp; - else -@@ -2523,6 +2521,8 @@ static void ath11k_dp_rx_h_mpdu(struct a - } - spin_unlock_bh(&ar->ab->base_lock); - -+ *fast_rx = false; -+ - rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc); - err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention); - if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) diff --git a/package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch b/package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch deleted file mode 100644 index 31db236d5f..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/718-e-mac80211-Deliver-the-frame-to-driver-tx-ops-directly.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f37e9b4a68d32d03346cbfc3cb4178b186c8f2a4 Mon Sep 17 00:00:00 2001 -From: Ramanathan Choodamani -Date: Fri, 17 Feb 2023 03:08:29 -0800 -Subject: [PATCH 5/7] mac80211: Deliver the frame to driver tx ops - directly - -Deliver the frame to driver directly in the forwarding path -to improve the throughput performance. - -Reset the fast xmit flag in ieee80211 datapath to ensure -other features handled as normal through the ath12k_dp_tx -function - -Signed-off-by: Balamurugan Mahalingam -Signed-off-by: Ramanathan Choodamani ---- - net/mac80211/tx.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -4567,6 +4567,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s - #ifdef CPTCFG_MAC80211_NSS_SUPPORT - ieee80211_xmit_nss_fixup(skb, dev); - #endif -+ skb->fast_xmit = 0; - - if (likely(!is_multicast_ether_addr(eth->h_dest))) - goto normal; -@@ -4838,7 +4839,43 @@ void ieee80211_8023_xmit_ap(struct ieee8 - netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, - struct net_device *dev) - { -- return __ieee80211_subif_start_xmit_8023(skb, dev, 0, 0, NULL); -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_tx_control control = {}; -+ struct sta_info *sta; -+ struct ieee80211_sta *pubsta = NULL; -+ -+ info->control.vif = &sdata->vif; -+ -+ if (skb->fast_xmit) { -+ info->control.flags = u32_encode_bits(IEEE80211_LINK_UNSPECIFIED, -+ IEEE80211_TX_CTRL_MLO_LINK); -+ info->flags = IEEE80211_TX_CTL_HW_80211_ENCAP; -+ -+ if (hweight16(sdata->vif.valid_links) > 1) { -+ rcu_read_lock(); -+ -+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) { -+ kfree_skb(skb); -+ goto out; -+ } -+ -+ if (!IS_ERR_OR_NULL(sta) && sta->uploaded) -+ pubsta = &sta->sta; -+ -+ control.sta = pubsta; -+ drv_tx(sdata->local, &control, skb); -+out: -+ rcu_read_unlock(); -+ } else { -+ control.sta = NULL; -+ drv_tx(sdata->local, &control, skb); -+ } -+ -+ return NETDEV_TX_OK; -+ } else { -+ return __ieee80211_subif_start_xmit_8023(skb, dev, 0, 0, NULL); -+ } - } - - netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch b/package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch deleted file mode 100644 index 52037816a1..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/902-022-ath11k-add-ap-ps-support.patch +++ /dev/null @@ -1,324 +0,0 @@ ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -30,6 +30,7 @@ - #include "spectral.h" - #include "wow.h" - #include "nss.h" -+#include "vendor.h" - - #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) - -@@ -637,6 +638,11 @@ struct ath11k_coex_info { - u32 pta_priority; - }; - -+enum ath11k_ap_ps_state { -+ ATH11K_AP_PS_STATE_OFF, -+ ATH11K_AP_PS_STATE_ON, -+}; -+ - struct ath11k { - struct ath11k_base *ab; - struct ath11k_pdev *pdev; -@@ -765,6 +771,8 @@ struct ath11k { - int monitor_vdev_id; - struct completion fw_mode_reset; - u8 ftm_msgref; -+ int ap_ps_enabled; -+ enum ath11k_ap_ps_state ap_ps_state; - #ifdef CPTCFG_ATH11K_DEBUGFS - struct ath11k_debug debug; - #endif ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4963,6 +4963,33 @@ static void ath11k_mac_dec_num_stations( - ar->num_stations--; - } - -+int ath11k_mac_ap_ps_recalc(struct ath11k *ar) -+{ -+ struct ath11k_vif *arvif; -+ bool has_sta_iface = false; -+ enum ath11k_ap_ps_state state = ATH11K_AP_PS_STATE_OFF; -+ int ret = 0; -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ if (arvif->vdev_type == WMI_VDEV_TYPE_STA) { -+ has_sta_iface = true; -+ break; -+ } -+ } -+ -+ if (!has_sta_iface && !ar->num_stations && ar->ap_ps_enabled) -+ state = ATH11K_AP_PS_STATE_ON; -+ -+ if (ar->ap_ps_state == state) -+ return ret; -+ -+ ret = ath11k_wmi_pdev_ap_ps_cmd_send(ar, ar->pdev->pdev_id, state); -+ if (!ret) -+ ar->ap_ps_state = state; -+ -+ return ret; -+} -+ - static int ath11k_mac_station_add(struct ath11k *ar, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -@@ -5002,6 +5029,12 @@ static int ath11k_mac_station_add(struct - ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n", - sta->addr, arvif->vdev_id); - -+ ret = ath11k_mac_ap_ps_recalc(ar); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret); -+ goto exit; -+ } -+ - if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) { - arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL); - if (!arsta->tx_stats) { -@@ -5158,6 +5191,9 @@ static int ath11k_mac_op_sta_state(struc - - kfree(arsta->tx_stats); - arsta->tx_stats = NULL; -+ ret = ath11k_mac_ap_ps_recalc(ar); -+ if (ret) -+ ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret); - - kfree(arsta->rx_stats); - arsta->rx_stats = NULL; -@@ -6566,6 +6602,7 @@ static void ath11k_mac_op_stop(struct ie - - clear_bit(ATH11K_CAC_RUNNING, &ar->dev_flags); - ar->state = ATH11K_STATE_OFF; -+ ar->ap_ps_state = ATH11K_AP_PS_STATE_OFF; - mutex_unlock(&ar->conf_mutex); - - cancel_delayed_work_sync(&ar->scan.timeout); -@@ -6973,7 +7010,6 @@ static int ath11k_mac_op_add_interface(s - arvif->vdev_id, ret); - goto err; - } -- - ar->num_created_vdevs++; - ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM created, vdev_id %d\n", - vif->addr, arvif->vdev_id); -@@ -7120,6 +7156,10 @@ static int ath11k_mac_op_add_interface(s - ret); - } - -+ ret = ath11k_mac_ap_ps_recalc(ar); -+ if (ret) -+ ath11k_warn(ar->ab, "failed to set ap ps ret %d\n", ret); -+ - mutex_unlock(&ar->conf_mutex); - - return 0; -@@ -7227,6 +7267,7 @@ err_vdev_del: - - /* Recalc txpower for remaining vdev */ - ath11k_mac_txpower_recalc(ar); -+ ath11k_mac_ap_ps_recalc(ar); - - ath11k_debugfs_remove_interface(arvif); - ---- a/drivers/net/wireless/ath/ath11k/mac.h -+++ b/drivers/net/wireless/ath/ath11k/mac.h -@@ -135,6 +135,7 @@ void ath11k_mac_11d_scan_start(struct at - void ath11k_mac_11d_scan_stop(struct ath11k *ar); - void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab); - -+int ath11k_mac_ap_ps_recalc(struct ath11k *ar); - void ath11k_mac_destroy(struct ath11k_base *ab); - void ath11k_mac_unregister(struct ath11k_base *ab); - int ath11k_mac_register(struct ath11k_base *ab); ---- a/drivers/net/wireless/ath/ath11k/vendor.c -+++ b/drivers/net/wireless/ath/ath11k/vendor.c -@@ -6,7 +6,6 @@ - #include - #include - #include "core.h" --#include "vendor.h" - #include "debug.h" - - static const struct nla_policy -@@ -21,6 +20,11 @@ ath11k_vendor_wlan_prio_policy[QCA_WLAN_ - [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 }, - }; - -+static const struct nla_policy -+ath11k_vendor_set_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = { -+ [QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_FLAG} -+}; -+ - static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy, - struct wireless_dev *wdev, - const void *data, -@@ -101,6 +105,51 @@ out: - return ret; - } - -+static int ath11k_vendor_set_wifi_config(struct wiphy *wihpy, -+ struct wireless_dev *wdev, -+ const void *data, -+ int data_len) -+{ -+ struct ieee80211_vif *vif; -+ struct ath11k_vif *arvif; -+ struct ath11k *ar; -+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1]; -+ int ret = 0; -+ -+ if (!wdev) -+ return -EINVAL; -+ -+ vif = wdev_to_ieee80211_vif(wdev); -+ if (!vif) -+ return -EINVAL; -+ -+ arvif = (struct ath11k_vif*)vif->drv_priv; -+ if (!arvif) -+ return -EINVAL; -+ -+ ar = arvif->ar; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+ ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data, data_len, -+ ath11k_vendor_set_wifi_config_policy, NULL); -+ if (ret) { -+ ath11k_warn(ar->ab, "invalid set wifi config policy attribute\n"); -+ goto exit; -+ } -+ -+ ar->ap_ps_enabled = nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX]); -+ ret = ath11k_mac_ap_ps_recalc(ar); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to send ap ps ret %d\n", ret); -+ goto exit; -+ } -+ -+exit: -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+} -+ - static struct wiphy_vendor_command ath11k_vendor_commands[] = { - { - .info.vendor_id = QCA_NL80211_VENDOR_ID, -@@ -108,8 +157,18 @@ static struct wiphy_vendor_command ath11 - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | - WIPHY_VENDOR_CMD_NEED_RUNNING, - .doit = ath11k_vendor_btcoex_configure, -- .policy = ath11k_vendor_btcoex_config_policy -- } -+ .policy = ath11k_vendor_btcoex_config_policy, -+ .maxattr = QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX -+ }, -+ { -+ .info.vendor_id = QCA_NL80211_VENDOR_ID, -+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | -+ WIPHY_VENDOR_CMD_NEED_RUNNING, -+ .doit = ath11k_vendor_set_wifi_config, -+ .policy = ath11k_vendor_set_wifi_config_policy, -+ .maxattr = QCA_WLAN_VENDOR_ATTR_CONFIG_MAX -+ }, - }; - - int ath11k_vendor_register(struct ath11k *ar) ---- a/drivers/net/wireless/ath/ath11k/vendor.h -+++ b/drivers/net/wireless/ath/ath11k/vendor.h -@@ -9,6 +9,9 @@ - #define QCA_NL80211_VENDOR_ID 0x001374 - - enum qca_nl80211_vendor_subcmds { -+ /* Wi-Fi configuration subcommand */ -+ QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION = 74, -+ - /* QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG: This command is used to - * enable/disable BTCOEX and set priority for different type of WLAN - * traffic over BT low priority traffic. This uses attributes in -@@ -58,7 +61,17 @@ enum qca_wlan_vendor_attr_wlan_prio { - QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_LAST - 1, - }; - -+/* Attributes for data used by -+ * QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION -+ */ -+enum qca_wlan_vendor_attr_config { -+ QCA_WLAN_VENDOR_ATTR_CONFIG_GTX = 57, - -+ /* keep last */ -+ QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST, -+ QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = -+ QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1, -+}; - - /** - * enum qca_wlan_vendor_attr_btcoex_config - Used by the vendor command ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -1446,6 +1446,38 @@ ath11k_wmi_rx_reord_queue_remove(struct - return ret; - } - -+int ath11k_wmi_pdev_ap_ps_cmd_send(struct ath11k *ar, u8 pdev_id, -+ u32 param_value) -+{ -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct wmi_pdev_ap_ps_cmd *cmd; -+ struct sk_buff *skb; -+ int ret; -+ -+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd)); -+ if (!skb) -+ return -ENOMEM; -+ -+ cmd = (struct wmi_pdev_ap_ps_cmd *)skb->data; -+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, -+ WMI_TAG_PDEV_GREEN_AP_PS_ENABLE_CMD) | -+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); -+ cmd->pdev_id = pdev_id; -+ cmd->param_value = param_value; -+ -+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to send ap ps enable/disable cmd\n"); -+ dev_kfree_skb(skb); -+ } -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "wmi pdev ap ps set pdev id %d value %d\n", -+ pdev_id, param_value); -+ -+ return ret; -+} -+ - int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id, - u32 param_value, u8 pdev_id) - { ---- a/drivers/net/wireless/ath/ath11k/wmi.h -+++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -3110,6 +3110,12 @@ struct set_fwtest_params { - u32 value; - }; - -+struct wmi_pdev_ap_ps_cmd { -+ u32 tlv_header; -+ u32 pdev_id; -+ u32 param_value; -+} __packed; -+ - struct wmi_fwtest_set_param_cmd_param { - u32 tlv_header; - u32 param_id; -@@ -6628,6 +6634,7 @@ int ath11k_wmi_pdev_non_srg_obss_bssid_e - u32 *bitmap); - int ath11k_send_coex_config_cmd(struct ath11k *ar, - struct coex_config_arg *coex_config); -+int ath11k_wmi_pdev_ap_ps_cmd_send(struct ath11k *ar, u8 pdev_id, u32 value); - int ath11k_wmi_send_obss_color_collision_cfg_cmd(struct ath11k *ar, u32 vdev_id, - u8 bss_color, u32 period, - bool enable); diff --git a/package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch b/package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch deleted file mode 100644 index 86812a1830..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/904-300-ath11k-nss_get_arvif_from_dev.patch +++ /dev/null @@ -1,113 +0,0 @@ -From fbe5a76d8c9ff1cf3f906a3c863928fc1adcbc95 Mon Sep 17 00:00:00 2001 -From: Karthikeyan Kathirvel -Date: Tue, 16 Feb 2021 13:44:39 +0530 -Subject: [PATCH] ath11k: Add mesh nss offload support - -- New capability advertising nss offload support for mesh type -- Mesh obj vap and link vap registration/clean up -- Command/event handling -- New .ch files in ath11k for nss mesh offload related debugs -- Tx/Rx data path on mesh link vap uses native wifi format -- Mesh obj vap handls packets in ether format. No Tx on Mesh - obj vap is expected as packets transmitted in slow path is - supposed to be encapsulated in 802.11 format. -- New mac80211-driver callbacks for mesh vap, mpath and mpp - configurations. - -Signed-off-by: Vasanthakumar Thiagarajan - -Change-Id: Ib6950344286ba18fab43586262c62dcd09557614 -Co-developed-by: Karthikeyan Kathirvel -Signed-off-by: Karthikeyan Kathirvel -Signed-off-by: Vasanthakumar Thiagarajan ---- - drivers/net/wireless/ath/ath11k/nss.c | 1482 ++++++++++++++++++++++++--- - ---- a/drivers/net/wireless/ath/ath11k/nss.c -+++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -35,6 +35,30 @@ ath11k_nss_get_vdev_opmode(struct ath11k - return ATH11K_NSS_OPMODE_UNKNOWN; - } - -+static struct ath11k_vif *ath11k_nss_get_arvif_from_dev(struct net_device *dev) -+{ -+ struct wireless_dev *wdev; -+ struct ieee80211_vif *vif; -+ struct ath11k_vif *arvif; -+ -+ if (!dev) -+ return NULL; -+ -+ wdev = dev->ieee80211_ptr; -+ if (!wdev) -+ return NULL; -+ -+ vif = wdev_to_ieee80211_vif(wdev); -+ if (!vif) -+ return NULL; -+ -+ arvif = (struct ath11k_vif *)vif->drv_priv; -+ if (!arvif) -+ return NULL; -+ -+ return arvif; -+} -+ - static void ath11k_nss_wifili_stats_sync(struct ath11k_base *ab, - struct nss_wifili_stats_sync_msg *wlsoc_stats) - { -@@ -294,6 +318,9 @@ void ath11k_nss_wifili_event_receive(str - - switch (msg_type) { - case NSS_WIFILI_INIT_MSG: -+ ab->nss.response = response; -+ complete(&ab->nss.complete); -+ break; - case NSS_WIFILI_PDEV_INIT_MSG: - case NSS_WIFILI_START_MSG: - case NSS_WIFILI_SOC_RESET_MSG: -@@ -302,7 +329,6 @@ void ath11k_nss_wifili_event_receive(str - ab->nss.response = response; - complete(&ab->nss.complete); - break; -- - case NSS_WIFILI_PEER_CREATE_MSG: - if (response != NSS_CMN_RESPONSE_EMSG) - break; -@@ -463,7 +489,9 @@ ath11k_nss_wifili_ext_callback_fn(struct - ath11k_nss_process_mic_error(ab, skb); - break; - default: -- kfree(skb); -+ ath11k_dbg(ab, ATH11K_DBG_NSS, "unknown packet type received in wifili ext cb %d", -+ wepm->pkt_type); -+ dev_kfree_skb_any(skb); - break; - } - } -@@ -785,24 +813,7 @@ ath11k_nss_vdev_special_data_receive(str - int data_offs = 0; - int ret = 0; - -- if (!dev) { -- dev_kfree_skb_any(skb); -- return; -- } -- -- wdev = dev->ieee80211_ptr; -- if (!wdev) { -- dev_kfree_skb_any(skb); -- return; -- } -- -- vif = wdev_to_ieee80211_vif(wdev); -- if (!vif) { -- dev_kfree_skb_any(skb); -- return; -- } -- -- arvif = (struct ath11k_vif *)vif->drv_priv; -+ arvif = ath11k_nss_get_arvif_from_dev(dev); - if (!arvif) { - dev_kfree_skb_any(skb); - return; diff --git a/package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch b/package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch deleted file mode 100644 index 734b6fb8c4..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/905-ath11k-add-support-memory-stats.patch +++ /dev/null @@ -1,946 +0,0 @@ -From 9c99e124a279391dbe2cef66226fd4e86bde8f4d Mon Sep 17 00:00:00 2001 -From: Maharaja Kennadyrajan -Date: Mon, 4 Jan 2021 23:46:53 +0530 -Subject: [PATCH 1/2] ath11k/mac80211: Add support to account memory stats - -Memory allocations in the driver & mac80211 are logged -and populate those values to the user space via debugfs. -This stats will give the snapshot of the memory being -used by the driver at the time of dumping these -memory stats. - -Command: -cat /sys/kernel/debug/ath11k/ipq8074\ hw2.0/memory_stats - -Sample output of the stats -MEMORY STATS IN BYTES: -malloc size : 6287583 -ce_ring_alloc size: 109308 -dma_alloc size:: 10831860 -htc_skb_alloc size: 3840 -wmi alloc size: 0 -per peer object: 4644 -rx_post_buf size: 5091840 -Total size: 22329075 - -User can disable/enable the memory stats accounting with -the below command. - -echo N > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/enable_memory_stats -where N = 0 to disable logging, 1 to enable the logging. - -Note: This should be enabled/disabled only after wifi is down. -User shouldn't enable/disable when the wifi is up to avoid -accounting the negative values which cause incorrect values -in the memory stats. - -Command: - -cat /sys/kernel/debug/ieee80211/phyX/memory_stats -memory stats: malloc_size: 108 - -Signed-off-by: Maharaja Kennadyrajan ---- - drivers/net/wireless/ath/ath11k/ce.c | 24 ++++ - drivers/net/wireless/ath/ath11k/core.c | 2 +- - drivers/net/wireless/ath/ath11k/core.h | 19 +++ - drivers/net/wireless/ath/ath11k/dbring.c | 3 + - drivers/net/wireless/ath/ath11k/debugfs.c | 115 ++++++++++++++++++ - drivers/net/wireless/ath/ath11k/debugfs.h | 29 +++++ - drivers/net/wireless/ath/ath11k/debugfs_sta.c | 4 + - drivers/net/wireless/ath/ath11k/dp.c | 13 ++ - drivers/net/wireless/ath/ath11k/hal.c | 6 + - drivers/net/wireless/ath/ath11k/htc.c | 5 + - drivers/net/wireless/ath/ath11k/mac.c | 15 ++- - drivers/net/wireless/ath/ath11k/nss.c | 46 +++++++ - drivers/net/wireless/ath/ath11k/peer.c | 5 + - drivers/net/wireless/ath/ath11k/wmi.c | 4 + - 15 files changed, 302 insertions(+), 3 deletions(-) - ---- a/drivers/net/wireless/ath/ath11k/ce.c -+++ b/drivers/net/wireless/ath/ath11k/ce.c -@@ -359,6 +359,9 @@ static int ath11k_ce_rx_post_pipe(struct - dev_kfree_skb_any(skb); - goto exit; - } -+ -+ ATH11K_MEMORY_STATS_INC(ab, ce_rx_pipe, skb->truesize); -+ - } - - exit: -@@ -427,6 +430,9 @@ static void ath11k_ce_recv_process_cb(st - __skb_queue_head_init(&list); - while (ath11k_ce_completed_recv_next(pipe, &skb, &nbytes) == 0) { - max_nbytes = skb->len + skb_tailroom(skb); -+ -+ ATH11K_MEMORY_STATS_DEC(ab, ce_rx_pipe, skb->truesize); -+ - dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr, - max_nbytes, DMA_FROM_DEVICE); - -@@ -620,6 +626,9 @@ ath11k_ce_alloc_ring(struct ath11k_base - if (ce_ring == NULL) - return ERR_PTR(-ENOMEM); - -+ ATH11K_MEMORY_STATS_INC(ab, ce_ring_alloc, -+ struct_size(ce_ring, skb, nentries)); -+ - ce_ring->nentries = nentries; - ce_ring->nentries_mask = nentries - 1; - -@@ -635,6 +644,9 @@ ath11k_ce_alloc_ring(struct ath11k_base - return ERR_PTR(-ENOMEM); - } - -+ ATH11K_MEMORY_STATS_INC(ab, ce_ring_alloc, -+ nentries * desc_sz + CE_DESC_RING_ALIGN); -+ - ce_ring->base_addr_ce_space_unaligned = base_addr; - - ce_ring->base_addr_owner_space = PTR_ALIGN( -@@ -814,6 +826,9 @@ static void ath11k_ce_rx_pipe_cleanup(st - continue; - - ring->skb[i] = NULL; -+ -+ ATH11K_MEMORY_STATS_DEC(ab, ce_rx_pipe, skb->truesize); -+ - dma_unmap_single(ab->dev, ATH11K_SKB_RXCB(skb)->paddr, - skb->len + skb_tailroom(skb), DMA_FROM_DEVICE); - dev_kfree_skb_any(skb); -@@ -992,6 +1007,9 @@ void ath11k_ce_free_pipes(struct ath11k_ - CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_ce_space_unaligned); -+ ATH11K_MEMORY_STATS_DEC(ab, ce_ring_alloc, -+ pipe->src_ring->nentries * desc_sz + -+ CE_DESC_RING_ALIGN); - kfree(pipe->src_ring); - pipe->src_ring = NULL; - } -@@ -1004,6 +1022,9 @@ void ath11k_ce_free_pipes(struct ath11k_ - CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_ce_space_unaligned); -+ ATH11K_MEMORY_STATS_DEC(ab, ce_ring_alloc, -+ pipe->dest_ring->nentries * desc_sz + -+ CE_DESC_RING_ALIGN); - kfree(pipe->dest_ring); - pipe->dest_ring = NULL; - } -@@ -1017,6 +1038,9 @@ void ath11k_ce_free_pipes(struct ath11k_ - CE_DESC_RING_ALIGN, - ce_ring->base_addr_owner_space_unaligned, - ce_ring->base_addr_ce_space_unaligned); -+ ATH11K_MEMORY_STATS_DEC(ab, ce_ring_alloc, -+ pipe->status_ring->nentries * desc_sz + -+ CE_DESC_RING_ALIGN); - kfree(pipe->status_ring); - pipe->status_ring = NULL; - } ---- a/drivers/net/wireless/ath/ath11k/core.c -+++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -2144,6 +2144,8 @@ int ath11k_core_pre_init(struct ath11k_b - if (nss_offload) - ab->nss.stats_enabled = 1; - -+ ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS; -+ - return 0; - } - EXPORT_SYMBOL(ath11k_core_pre_init); ---- a/drivers/net/wireless/ath/ath11k/core.h -+++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -930,6 +930,23 @@ struct ath11k_num_vdevs_peers { - u32 num_peers; - }; - -+struct ath11k_memory_stats { -+ /* Account kzalloc and valloc */ -+ atomic_t malloc_size; -+ /* Account dma_alloc in dp.c & hal.c */ -+ atomic_t dma_alloc; -+ /* Account memory used in ce rings */ -+ atomic_t ce_ring_alloc; -+ /* Account memory used in htc_send */ -+ atomic_t htc_skb_alloc; -+ /* Account memory used in wmi tx skb alloc */ -+ atomic_t wmi_tx_skb_alloc; -+ /* Account memory consumed for peer object */ -+ atomic_t per_peer_object; -+ /* Account memory used in ce rx pipe */ -+ atomic_t ce_rx_pipe; -+}; -+ - /* Master structure to hold the hw data which may be used in core module */ - struct ath11k_base { - enum ath11k_hw_rev hw_rev; -@@ -1019,6 +1036,7 @@ struct ath11k_base { - enum ath11k_dfs_region dfs_region; - #ifdef CPTCFG_ATH11K_DEBUGFS - struct dentry *debugfs_soc; -+ struct ath11k_memory_stats memory_stats; - #endif - struct ath11k_soc_dp_stats soc_stats; - -@@ -1085,6 +1103,7 @@ struct ath11k_base { - - atomic_t num_max_allowed; - struct ath11k_num_vdevs_peers *num_vdevs_peers; -+ bool enable_memory_stats; - - u32 rx_hash; - bool stats_disable; ---- a/drivers/net/wireless/ath/ath11k/dbring.c -+++ b/drivers/net/wireless/ath/ath11k/dbring.c -@@ -143,6 +143,7 @@ static int ath11k_dbring_fill_bufs(struc - break; - } - num_remain--; -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, size); - } - - spin_unlock_bh(&srng->lock); -@@ -392,6 +393,8 @@ void ath11k_dbring_buf_cleanup(struct at - idr_remove(&ring->bufs_idr, buf_id); - dma_unmap_single(ar->ab->dev, buff->paddr, - ring->buf_sz, DMA_FROM_DEVICE); -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(*buff) + -+ ring->buf_sz + ring->buf_align - 1); - kfree(buff->payload); - kfree(buff); - } ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -801,6 +801,8 @@ static ssize_t ath11k_debugfs_dump_soc_d - if (!buf) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, size); -+ - len += scnprintf(buf + len, size - len, "SOC RX STATS:\n\n"); - len += scnprintf(buf + len, size - len, "err ring pkts: %u\n", - soc_stats->err_ring_pkts); -@@ -842,6 +844,8 @@ static ssize_t ath11k_debugfs_dump_soc_d - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, size); -+ - return retval; - } - -@@ -1094,6 +1098,106 @@ static const struct file_operations fops - .write = ath11k_write_stats_disable, - }; - -+static ssize_t -+ath11k_debug_read_enable_memory_stats(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k_base *ab = file->private_data; -+ char buf[10]; -+ size_t len; -+ -+ len = scnprintf(buf, sizeof(buf), "%d\n", ab->enable_memory_stats); -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+} -+ -+static ssize_t -+ath11k_debug_write_enable_memory_stats(struct file *file, -+ const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k_base *ab = file->private_data; -+ bool enable; -+ int ret; -+ -+ if (kstrtobool_from_user(ubuf, count, &enable)) -+ return -EINVAL; -+ -+ if (enable == ab->enable_memory_stats) { -+ ret = count; -+ goto exit; -+ } -+ -+ ab->enable_memory_stats = enable; -+ ret = count; -+exit: -+ return ret; -+} -+ -+static const struct file_operations fops_enable_memory_stats = { -+ .read = ath11k_debug_read_enable_memory_stats, -+ .write = ath11k_debug_write_enable_memory_stats, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+ .open = simple_open, -+}; -+ -+static ssize_t ath11k_debug_dump_memory_stats(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k_base *ab = file->private_data; -+ struct ath11k_memory_stats *memory_stats = &ab->memory_stats; -+ int len = 0, retval; -+ const int size = 4096; -+ -+ char *buf; -+ -+ buf = kzalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ len += scnprintf(buf + len, size - len, "MEMORY STATS IN BYTES:\n"); -+ len += scnprintf(buf + len, size - len, "malloc size : %u\n", -+ atomic_read(&memory_stats->malloc_size)); -+ len += scnprintf(buf + len, size - len, "ce_ring_alloc size: %u\n", -+ atomic_read(&memory_stats->ce_ring_alloc)); -+ len += scnprintf(buf + len, size - len, "dma_alloc size:: %u\n", -+ atomic_read(&memory_stats->dma_alloc)); -+ len += scnprintf(buf + len, size - len, "htc_skb_alloc size: %u\n", -+ atomic_read(&memory_stats->htc_skb_alloc)); -+ len += scnprintf(buf + len, size - len, "wmi tx skb alloc size: %u\n", -+ atomic_read(&memory_stats->wmi_tx_skb_alloc)); -+ len += scnprintf(buf + len, size - len, "per peer object: %u\n", -+ atomic_read(&memory_stats->per_peer_object)); -+ len += scnprintf(buf + len, size - len, "rx_post_buf size: %u\n", -+ atomic_read(&memory_stats->ce_rx_pipe)); -+ len += scnprintf(buf + len, size - len, "Total size: %u\n\n", -+ (atomic_read(&memory_stats->malloc_size) + -+ atomic_read(&memory_stats->ce_ring_alloc) + -+ atomic_read(&memory_stats->dma_alloc) + -+ atomic_read(&memory_stats->htc_skb_alloc) + -+ atomic_read(&memory_stats->wmi_tx_skb_alloc) + -+ atomic_read(&memory_stats->per_peer_object) + -+ atomic_read(&memory_stats->ce_rx_pipe))); -+ -+ if (len > size) -+ len = size; -+ -+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ kfree(buf); -+ -+ return retval; -+} -+ -+static const struct file_operations fops_memory_stats = { -+ .read = ath11k_debug_dump_memory_stats, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; -+ - int ath11k_debugfs_pdev_create(struct ath11k_base *ab) - { - if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) -@@ -1112,6 +1216,12 @@ int ath11k_debugfs_pdev_create(struct at - debugfs_create_file("rx_hash", 0600, ab->debugfs_soc, ab, - &fops_soc_rx_hash); - -+ debugfs_create_file("enable_memory_stats", 0600, ab->debugfs_soc, -+ ab, &fops_enable_memory_stats); -+ -+ debugfs_create_file("memory_stats", 0600, ab->debugfs_soc, ab, -+ &fops_memory_stats); -+ - - return 0; - } -@@ -1742,6 +1852,8 @@ static ssize_t ath11k_dump_mgmt_stats(st - if (!buf) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, size); -+ - mutex_lock(&ar->conf_mutex); - spin_lock_bh(&ar->data_lock); - -@@ -1792,6 +1904,9 @@ static ssize_t ath11k_dump_mgmt_stats(st - ret = simple_read_from_buffer(ubuf, count, ppos, buf, len); - mutex_unlock(&ar->conf_mutex); - kfree(buf); -+ -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, size); -+ - return ret; - } - ---- a/drivers/net/wireless/ath/ath11k/debugfs.h -+++ b/drivers/net/wireless/ath/ath11k/debugfs.h -@@ -10,6 +10,7 @@ - - #define ATH11K_TX_POWER_MAX_VAL 70 - #define ATH11K_TX_POWER_MIN_VAL 0 -+#define ATH11K_DEBUG_ENABLE_MEMORY_STATS 1 - - /* htt_dbg_ext_stats_type */ - enum ath11k_dbg_htt_ext_stats_type { -@@ -263,6 +264,24 @@ struct ath11k_fw_dbglog { - }; - - #ifdef CPTCFG_ATH11K_DEBUGFS -+#define ATH11K_MEMORY_STATS_INC(_struct, _field, _size) \ -+do { \ -+ if (ath11k_debug_is_memory_stats_enabled(_struct)) \ -+ atomic_add(_size, &_struct->memory_stats._field); \ -+} while(0) -+ -+#define ATH11K_MEMORY_STATS_DEC(_struct, _field, _size) \ -+do { \ -+ if (ath11k_debug_is_memory_stats_enabled(_struct)) \ -+ atomic_sub(_size, &_struct->memory_stats._field); \ -+} while(0) -+ -+#else -+#define ATH11K_MEMORY_STATS_INC(_struct, _field, _size) -+#define ATH11K_MEMORY_STATS_DEC(_struct, _field, _size) -+#endif -+ -+#ifdef CPTCFG_ATH11K_DEBUGFS - int ath11k_debugfs_soc_create(struct ath11k_base *ab); - void ath11k_debugfs_soc_destroy(struct ath11k_base *ab); - int ath11k_debugfs_pdev_create(struct ath11k_base *ab); -@@ -313,6 +332,11 @@ void ath11k_debugfs_add_dbring_entry(str - enum ath11k_dbg_dbr_event event, - struct hal_srng *srng); - -+static inline int ath11k_debug_is_memory_stats_enabled(struct ath11k_base *ab) -+{ -+ return ab->enable_memory_stats; -+} -+ - #else - static inline int ath11k_debugfs_soc_create(struct ath11k_base *ab) - { -@@ -375,6 +399,11 @@ static inline bool ath11k_debugfs_is_pkt - return false; - } - -+static inline int ath11k_debug_is_memory_stats_enabled(struct ath11k_base *ab) -+{ -+ return 0; -+} -+ - static inline int ath11k_debugfs_rx_filter(struct ath11k *ar) - { - return 0; ---- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c -@@ -468,6 +468,8 @@ static ssize_t ath11k_dbg_sta_dump_rx_st - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, size); -+ - mutex_unlock(&ar->conf_mutex); - return retval; - } ---- a/drivers/net/wireless/ath/ath11k/dp.c -+++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -115,6 +115,8 @@ void ath11k_dp_srng_cleanup(struct ath11 - dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned, - ring->paddr_unaligned); - -+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, ring->size); -+ - ring->vaddr_unaligned = NULL; - } - -@@ -278,6 +280,8 @@ int ath11k_dp_srng_setup(struct ath11k_b - if (!ring->vaddr_unaligned) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, ring->size); -+ - ring->vaddr = PTR_ALIGN(ring->vaddr_unaligned, HAL_RING_BASE_ALIGN); - ring->paddr = ring->paddr_unaligned + ((unsigned long)ring->vaddr - - (unsigned long)ring->vaddr_unaligned); -@@ -514,6 +518,7 @@ static void ath11k_dp_scatter_idle_link_ - dma_free_coherent(ab->dev, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX, - slist[i].vaddr, slist[i].paddr); - slist[i].vaddr = NULL; -+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX); - } - } - -@@ -551,6 +556,7 @@ static int ath11k_dp_scatter_idle_link_d - ret = -ENOMEM; - goto err; - } -+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX); - } - - scatter_idx = 0; -@@ -605,6 +611,7 @@ ath11k_dp_link_desc_bank_free(struct ath - link_desc_banks[i].vaddr_unaligned, - link_desc_banks[i].paddr_unaligned); - link_desc_banks[i].vaddr_unaligned = NULL; -+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, link_desc_banks[i].size); - } - } - } -@@ -638,6 +645,7 @@ static int ath11k_dp_link_desc_bank_allo - ((unsigned long)desc_bank[i].vaddr - - (unsigned long)desc_bank[i].vaddr_unaligned); - desc_bank[i].size = desc_sz; -+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, desc_bank[i].size); - } - - return 0; -@@ -1042,8 +1050,11 @@ static int ath11k_dp_tx_pending_cleanup( - void ath11k_dp_free(struct ath11k_base *ab) - { - struct ath11k_dp *dp = &ab->dp; -+ size_t size = 0; - int i; - -+ size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; -+ - ath11k_dp_link_desc_cleanup(ab, dp->link_desc_banks, - HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); - -@@ -1057,6 +1068,7 @@ void ath11k_dp_free(struct ath11k_base * - ath11k_dp_tx_pending_cleanup, ab); - idr_destroy(&dp->tx_ring[i].txbuf_idr); - spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock); -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, size); - kfree(dp->tx_ring[i].tx_status); - } - -@@ -1114,6 +1126,7 @@ int ath11k_dp_alloc(struct ath11k_base * - ret = -ENOMEM; - goto fail_cmn_srng_cleanup; - } -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, size); - } - - for (i = 0; i < HAL_DSCP_TID_MAP_TBL_NUM_ENTRIES_MAX; i++) ---- a/drivers/net/wireless/ath/ath11k/hal.c -+++ b/drivers/net/wireless/ath/ath11k/hal.c -@@ -201,6 +201,8 @@ static int ath11k_hal_alloc_cont_rdp(str - if (!hal->rdp.vaddr) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, size); -+ - return 0; - } - -@@ -215,6 +217,7 @@ static void ath11k_hal_free_cont_rdp(str - size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; - dma_free_coherent(ab->dev, size, - hal->rdp.vaddr, hal->rdp.paddr); -+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, size); - hal->rdp.vaddr = NULL; - } - -@@ -229,6 +232,8 @@ static int ath11k_hal_alloc_cont_wrp(str - if (!hal->wrp.vaddr) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, size); -+ - return 0; - } - -@@ -243,6 +248,7 @@ static void ath11k_hal_free_cont_wrp(str - size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS; - dma_free_coherent(ab->dev, size, - hal->wrp.vaddr, hal->wrp.paddr); -+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, size); - hal->wrp.vaddr = NULL; - } - ---- a/drivers/net/wireless/ath/ath11k/htc.c -+++ b/drivers/net/wireless/ath/ath11k/htc.c -@@ -28,6 +28,7 @@ struct sk_buff *ath11k_htc_alloc_skb(str - static void ath11k_htc_control_tx_complete(struct ath11k_base *ab, - struct sk_buff *skb) - { -+ ATH11K_MEMORY_STATS_DEC(ab, htc_skb_alloc, skb->truesize); - kfree_skb(skb); - } - -@@ -609,6 +610,7 @@ int ath11k_htc_connect_service(struct at - bool disable_credit_flow_ctrl = false; - u16 message_id, service_id, flags = 0; - u8 tx_alloc = 0; -+ size_t truesize; - - /* special case for HTC pseudo control service */ - if (conn_req->service_id == ATH11K_HTC_SVC_ID_RSVD_CTRL) { -@@ -632,6 +634,7 @@ int ath11k_htc_connect_service(struct at - return -ENOMEM; - } - -+ truesize = skb->truesize; - length = sizeof(*req_msg); - skb_put(skb, length); - memset(skb->data, 0, length); -@@ -667,6 +670,8 @@ int ath11k_htc_connect_service(struct at - return status; - } - -+ ATH11K_MEMORY_STATS_INC(ab, htc_skb_alloc, truesize); -+ - /* wait for response */ - time_left = wait_for_completion_timeout(&htc->ctl_resp, - ATH11K_HTC_CONN_SVC_TIMEOUT_HZ); -@@ -768,11 +773,13 @@ int ath11k_htc_start(struct ath11k_htc * - int status = 0; - struct ath11k_base *ab = htc->ab; - struct ath11k_htc_setup_complete_extended *msg; -+ size_t truesize; - - skb = ath11k_htc_build_tx_ctrl_skb(htc->ab); - if (!skb) - return -ENOMEM; - -+ truesize = skb->truesize; - skb_put(skb, sizeof(*msg)); - memset(skb->data, 0, skb->len); - -@@ -791,6 +798,8 @@ int ath11k_htc_start(struct ath11k_htc * - return status; - } - -+ ATH11K_MEMORY_STATS_INC(ab, htc_skb_alloc, truesize); -+ - return 0; - } - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4058,6 +4058,8 @@ static int ath11k_mac_op_hw_scan(struct - goto exit; - } - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, sizeof(*arg)); -+ - ath11k_wmi_start_scan_init(ar, arg); - arg->vdev_id = arvif->vdev_id; - arg->scan_id = ATH11K_SCAN_ID; -@@ -4071,6 +4073,8 @@ static int ath11k_mac_op_hw_scan(struct - arg->extraie.len = req->ie_len; - } - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, req->ie_len); -+ - if (req->n_ssids) { - arg->num_ssids = req->n_ssids; - for (i = 0; i < arg->num_ssids; i++) { -@@ -4157,9 +4161,16 @@ static int ath11k_mac_op_hw_scan(struct - exit: - if (arg) { - kfree(arg->chan_list); -- kfree(arg->extraie.ptr); -- kfree(arg); -- } -+ -+ if (arg->extraie.ptr) { -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, req->ie_len); -+ kfree(arg->extraie.ptr); -+ } -+ -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(*arg)); -+ -+ kfree(arg); -+ } - - mutex_unlock(&ar->conf_mutex); - -@@ -8113,6 +8124,8 @@ ath11k_mac_update_active_vif_chan(struct - if (!arg.vifs) - return; - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, sizeof(arg.vifs[0])); -+ - ieee80211_iterate_active_interfaces_atomic(ar->hw, - IEEE80211_IFACE_ITER_NORMAL, - ath11k_mac_change_chanctx_fill_iter, -@@ -8120,6 +8133,8 @@ ath11k_mac_update_active_vif_chan(struct - - ath11k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs); - -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(arg.vifs[0])); -+ - kfree(arg.vifs); - } - ---- a/drivers/net/wireless/ath/ath11k/nss.c -+++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -1052,6 +1052,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 - default: - return -EINVAL; - } -+ -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, sizeof(*vdev_msg)); -+ - /* TODO: Convert to function for conversion in case of many - * such commands - */ -@@ -1082,6 +1085,7 @@ int ath11k_nss_vdev_set_cmd(struct ath11 - ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev set cmd success cmd:%d val:%d\n", - cmd, val); - free: -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, sizeof(*vdev_msg)); - kfree(vdev_msg); - return status; - } -@@ -1098,6 +1102,9 @@ static int ath11k_nss_vdev_configure(str - if (!vdev_msg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, -+ sizeof(struct nss_wifi_vdev_msg)); -+ - vdev_cfg = &vdev_msg->msg.vdev_config; - - vdev_cfg->radio_ifnum = ar->nss.if_num; -@@ -1133,6 +1140,8 @@ static int ath11k_nss_vdev_configure(str - - ret = 0; - free: -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, -+ sizeof(struct nss_wifi_vdev_msg)); - kfree(vdev_msg); - - return ret; -@@ -1357,6 +1366,9 @@ int ath11k_nss_vdev_up(struct ath11k_vif - if (!vdev_msg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, -+ sizeof(struct nss_wifi_vdev_msg)); -+ - vdev_en = &vdev_msg->msg.vdev_enable; - - ether_addr_copy(vdev_en->mac_addr, arvif->vif->addr); -@@ -1381,6 +1393,8 @@ int ath11k_nss_vdev_up(struct ath11k_vif - if (ap_vlan_arvif->nss.added) - ath11k_nss_ext_vdev_up(ap_vlan_arvif); - free: -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, -+ sizeof(struct nss_wifi_vdev_msg)); - kfree(vdev_msg); - return ret; - } -@@ -1404,6 +1418,8 @@ int ath11k_nss_vdev_down(struct ath11k_v - if (!vdev_msg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, -+ sizeof(struct nss_wifi_vdev_msg)); - nss_wifi_vdev_msg_init(vdev_msg, arvif->nss.if_num, - NSS_WIFI_VDEV_INTERFACE_DOWN_MSG, - sizeof(struct nss_wifi_vdev_disable_msg), -@@ -1423,6 +1439,8 @@ int ath11k_nss_vdev_down(struct ath11k_v - list) - ath11k_nss_ext_vdev_down(ap_vlan_arvif); - free: -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, -+ sizeof(struct nss_wifi_vdev_msg)); - kfree(vdev_msg); - return ret; - } -@@ -1875,6 +1893,9 @@ int ath11k_nss_set_peer_sec_type(struct - if (!wlmsg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ar->ab, malloc_size, -+ sizeof(struct nss_wifili_msg)); -+ - sec_msg = &wlmsg->msg.securitymsg; - sec_msg->peer_id = peer->peer_id; - -@@ -1906,6 +1927,8 @@ int ath11k_nss_set_peer_sec_type(struct - ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss peer id %d security cfg complete\n", - peer->peer_id); - free: -+ ATH11K_MEMORY_STATS_DEC(ar->ab, malloc_size, -+ sizeof(struct nss_wifili_msg)); - kfree(wlmsg); - return status; - } -@@ -2593,6 +2616,7 @@ static void ath11k_nss_tx_desc_mem_free( - ab->nss.tx_desc_vaddr[i], - ab->nss.tx_desc_paddr[i]); - ab->nss.tx_desc_vaddr[i] = NULL; -+ ATH11K_MEMORY_STATS_DEC(ab, dma_alloc, ab->nss.tx_desc_size[i]); - } - - ath11k_dbg(ab, ATH11K_DBG_NSS, "allocated tx desc mem freed\n"); -@@ -2624,6 +2648,8 @@ static int ath11k_nss_tx_desc_mem_alloc( - ab->nss.tx_desc_size[curr_page_idx] = alloc_size; - curr_page_idx++; - -+ ATH11K_MEMORY_STATS_INC(ab, dma_alloc, alloc_size); -+ - ath11k_dbg(ab, ATH11K_DBG_NSS, - "curr page %d, allocated %d, total allocated %d\n", - curr_page_idx, alloc_size, i + alloc_size); -@@ -2795,6 +2821,8 @@ static int ath11k_nss_init(struct ath11k - if (!wlmsg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - wim = &wlmsg->msg.init; - - wim->target_type = target_type; -@@ -2914,6 +2942,7 @@ unregister: - nss_unregister_wifili_if(ab->nss.if_num); - free: - ath11k_nss_tx_desc_mem_free(ab); -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); - kfree(wlmsg); - return -EINVAL; - } -@@ -3031,6 +3060,8 @@ int ath11k_nss_pdev_init(struct ath11k_b - goto unregister; - } - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - pdevmsg = &wlmsg->msg.pdevmsg; - - pdevmsg->radio_id = radio_id; -@@ -3077,6 +3108,8 @@ int ath11k_nss_pdev_init(struct ath11k_b - goto free; - } - -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - kfree(wlmsg); - - /* Disable nss sojourn stats by default */ -@@ -3095,6 +3128,7 @@ int ath11k_nss_pdev_init(struct ath11k_b - return 0; - - free: -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); - kfree(wlmsg); - unregister: - nss_unregister_wifili_radio_if(ar->nss.if_num); -@@ -3117,6 +3151,8 @@ int ath11k_nss_start(struct ath11k_base - if (!wlmsg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; - - /* Empty message for NSS Start message */ -@@ -3157,6 +3193,7 @@ int ath11k_nss_start(struct ath11k_base - ath11k_dbg(ab, ATH11K_DBG_NSS, "nss start success\n"); - - free: -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); - kfree(wlmsg); - return ret; - } -@@ -3175,6 +3212,8 @@ static void ath11k_nss_reset(struct ath1 - return; - } - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; - - /* Empty message for NSS Reset message */ -@@ -3213,6 +3252,7 @@ static void ath11k_nss_reset(struct ath1 - nss_unregister_wifili_if(ab->nss.if_num); - - free: -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); - kfree(wlmsg); - } - -@@ -3228,6 +3268,8 @@ static int ath11k_nss_stop(struct ath11k - if (!wlmsg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; - - /* Empty message for Stop command */ -@@ -3267,6 +3309,8 @@ static int ath11k_nss_stop(struct ath11k - /* NSS Stop success */ - ret = 0; - free: -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - kfree(wlmsg); - return ret; - } -@@ -3292,6 +3336,8 @@ int ath11k_nss_pdev_deinit(struct ath11k - if (!wlmsg) - return -ENOMEM; - -+ ATH11K_MEMORY_STATS_INC(ab, malloc_size, sizeof(struct nss_wifili_msg)); -+ - deinit = &wlmsg->msg.pdevdeinit; - deinit->ifnum = radio_id; - -@@ -3337,6 +3383,7 @@ int ath11k_nss_pdev_deinit(struct ath11k - nss_dynamic_interface_dealloc_node(ar->nss.if_num, dyn_if_type); - nss_unregister_wifili_radio_if(ar->nss.if_num); - free: -+ ATH11K_MEMORY_STATS_DEC(ab, malloc_size, sizeof(struct nss_wifili_msg)); - kfree(wlmsg); - return ret; - } ---- a/drivers/net/wireless/ath/ath11k/peer.c -+++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -794,6 +794,9 @@ int ath11k_peer_delete(struct ath11k *ar - if (ret) - return ret; - -+ ATH11K_MEMORY_STATS_DEC(ar->ab, per_peer_object, -+ sizeof(struct ath11k_peer)); -+ - ar->num_peers--; - - return 0; -@@ -902,6 +905,8 @@ int ath11k_peer_create(struct ath11k *ar - arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT; - } - -+ ATH11K_MEMORY_STATS_INC(ar->ab, per_peer_object, sizeof(*peer)); -+ - ar->num_peers++; - - spin_unlock_bh(&ar->ab->base_lock); ---- a/drivers/net/wireless/ath/ath11k/wmi.c -+++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -623,6 +623,8 @@ struct sk_buff *ath11k_wmi_alloc_skb(str - if (!skb) - return NULL; - -+ ATH11K_MEMORY_STATS_INC(ab, wmi_tx_skb_alloc, skb->truesize); -+ - skb_reserve(skb, WMI_SKB_HEADROOM); - if (!IS_ALIGNED((unsigned long)skb->data, 4)) - ath11k_warn(ab, "unaligned WMI skb data\n"); -@@ -7314,6 +7316,7 @@ static void ath11k_wmi_htc_tx_complete(s - u8 eid; - - eid = ATH11K_SKB_CB(skb)->eid; -+ ATH11K_MEMORY_STATS_DEC(ab, wmi_tx_skb_alloc, skb->truesize); - dev_kfree_skb(skb); - - if (eid >= ATH11K_HTC_EP_COUNT) -@@ -9107,6 +9110,7 @@ static void ath11k_wmi_tlv_op_rx(struct - } - - out: -+ ATH11K_MEMORY_STATS_DEC(ab, wmi_tx_skb_alloc, skb->truesize); - dev_kfree_skb(skb); - } - diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch b/package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch deleted file mode 100644 index c61c206c41..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/911-335-0006-ath11k-add-simple-tx-handler-for-AP-mode.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 9600bc899bd28386375f5b5902a33f1984ce9da8 Mon Sep 17 00:00:00 2001 -From: Venkateswara Naralasetty -Date: Thu, 18 Nov 2021 13:11:02 +0530 -Subject: [PATCH] ath11k: add simple tx handler for AP mode - -Add simple tx handler for AP mode to skip cheks which are not -applicable for AP mode. - -Signed-off-by: Venkateswara Naralasetty ---- - drivers/net/wireless/ath/ath11k/dp_tx.c | 123 +++++++++++++++++++++++++++++ - drivers/net/wireless/ath/ath11k/dp_tx.h | 2 + - drivers/net/wireless/ath/ath11k/hal_desc.h | 6 ++ - drivers/net/wireless/ath/ath11k/mac.c | 3 + - 4 files changed, 134 insertions(+) - ---- a/drivers/net/wireless/ath/ath11k/dp_tx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -103,6 +103,128 @@ static int ath11k_dp_prepare_htt_metadat - return 0; - } - -+int ath11k_dp_tx_simple(struct ath11k *ar, struct ath11k_vif *arvif, -+ struct sk_buff *skb, struct ath11k_sta *arsta) -+{ -+ struct ath11k_base *ab = ar->ab; -+ struct ath11k_dp *dp = &ab->dp; -+ struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb); -+ struct hal_srng *tcl_ring; -+ struct dp_tx_ring *tx_ring; -+ struct hal_tcl_data_cmd *tcl_desc; -+ void *hal_tcl_desc; -+ dma_addr_t paddr; -+ u8 pool_id; -+ u8 hal_ring_id; -+ int ret; -+ u32 idr; -+ u8 tcl_ring_id, ring_id, max_tx_ring; -+ u8 buf_id; -+ u32 desc_id; -+ u8 ring_selector; -+ -+ max_tx_ring = ab->hw_params.max_tx_ring; -+ -+ if (unlikely(atomic_read(&ab->num_max_allowed) > DP_TX_COMP_MAX_ALLOWED)) { -+ atomic_inc(&ab->soc_stats.tx_err.max_fail); -+ ret = -EINVAL; -+ } -+ -+ ring_selector = smp_processor_id(); -+ pool_id = ring_selector; -+ -+ if (max_tx_ring == 1) { -+ ring_id = 0; -+ tcl_ring_id = 0; -+ } else { -+ ring_id = ring_selector % max_tx_ring; -+ tcl_ring_id = (ring_id == DP_TCL_NUM_RING_MAX) ? -+ DP_TCL_NUM_RING_MAX - 1 : ring_id; -+ } -+ -+ buf_id = tcl_ring_id + HAL_RX_BUF_RBM_SW0_BM; -+ tx_ring = &dp->tx_ring[tcl_ring_id]; -+ -+ spin_lock_bh(&tx_ring->tx_idr_lock); -+ idr = find_first_zero_bit(tx_ring->idrs, DP_TX_IDR_SIZE); -+ if (unlikely(idr >= DP_TX_IDR_SIZE)) { -+ spin_unlock_bh(&tx_ring->tx_idr_lock); -+ return -ENOSPC; -+ } -+ -+ set_bit(idr, tx_ring->idrs); -+ tx_ring->idr_pool[idr].id = idr; -+ tx_ring->idr_pool[idr].buf = skb; -+ spin_unlock_bh(&tx_ring->tx_idr_lock); -+ -+ desc_id = FIELD_PREP(DP_TX_DESC_ID_MAC_ID, ar->pdev_idx) | -+ FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, idr) | -+ FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id); -+ -+ skb_cb->vif = arvif->vif; -+ skb_cb->ar = ar; -+ -+ paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(ab->dev, paddr))) { -+ atomic_inc(&ab->soc_stats.tx_err.misc_fail); -+ ath11k_warn(ab, "failed to DMA map data Tx buffer\n"); -+ ret = -ENOMEM; -+ goto fail_remove_idr; -+ } -+ -+ skb_cb->paddr = paddr; -+ -+ hal_ring_id = tx_ring->tcl_data_ring.ring_id; -+ tcl_ring = &ab->hal.srng_list[hal_ring_id]; -+ -+ spin_lock_bh(&tcl_ring->lock); -+ ath11k_hal_srng_access_begin(ab, tcl_ring); -+ -+ hal_tcl_desc = (void *)ath11k_hal_srng_src_get_next_entry(ab, tcl_ring); -+ if (unlikely(!hal_tcl_desc)) { -+ ath11k_hal_srng_access_end(ab, tcl_ring); -+ spin_unlock_bh(&tcl_ring->lock); -+ ab->soc_stats.tx_err.desc_na[tcl_ring_id]++; -+ ret = -ENOMEM; -+ goto fail_remove_idr; -+ } -+ -+ tcl_desc = (struct hal_tcl_data_cmd *)(hal_tcl_desc + sizeof(struct hal_tlv_hdr)); -+ tcl_desc->info3 = 0; -+ tcl_desc->info4 = 0; -+ -+ tcl_desc->buf_addr_info.info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr); -+ tcl_desc->buf_addr_info.info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, -+ ((uint64_t)paddr >> HAL_ADDR_MSB_REG_SHIFT)); -+ tcl_desc->buf_addr_info.info1 |= FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, buf_id) | -+ FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, desc_id); -+ tcl_desc->info0 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_SEARCH_TYPE, -+ arvif->search_type) | -+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE, HAL_TCL_ENCAP_TYPE_ETHERNET) | -+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ADDR_EN, arvif->hal_addr_search_flags) | -+ FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, arvif->tcl_metadata); -+ -+ tcl_desc->info1 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_DATA_LEN, skb->len); -+ -+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) -+ tcl_desc->info1 |= TX_IP_CHECKSUM; -+ -+ tcl_desc->info2 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ar->lmac_id); -+ -+ ath11k_hal_srng_access_end(ab, tcl_ring); -+ spin_unlock_bh(&tcl_ring->lock); -+ -+ atomic_inc(&ar->dp.num_tx_pending); -+ atomic_inc(&ab->num_max_allowed); -+ -+ return 0; -+ -+fail_remove_idr: -+ tx_ring->idr_pool[idr].id = -1; -+ clear_bit(idr, tx_ring->idrs); -+ return ret; -+} -+ - int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct ath11k_sta *arsta, struct sk_buff *skb) - { ---- a/drivers/net/wireless/ath/ath11k/dp_tx.h -+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h -@@ -218,6 +218,8 @@ void ath11k_dp_tx_update_txcompl(struct - int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab); - int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, - struct ath11k_sta *arsta, struct sk_buff *skb); -+int ath11k_dp_tx_simple(struct ath11k *ar, struct ath11k_vif *arvif, -+ struct sk_buff *skb, struct ath11k_sta *arsta); - void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id); - int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, - enum hal_reo_cmd_type type, ---- a/drivers/net/wireless/ath/ath11k/hal_desc.h -+++ b/drivers/net/wireless/ath/ath11k/hal_desc.h -@@ -952,6 +952,12 @@ struct hal_reo_flush_cache { - u32 rsvd0[6]; - } __packed; - -+#define TX_IP_CHECKSUM HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN | \ -+ HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN | \ -+ HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN | \ -+ HAL_TCL_DATA_CMD_INFO1_TCP4_CKSUM_EN | \ -+ HAL_TCL_DATA_CMD_INFO1_TCP6_CKSUM_EN -+ - #define HAL_TCL_DATA_CMD_INFO0_DESC_TYPE BIT(0) - #define HAL_TCL_DATA_CMD_INFO0_EPD BIT(1) - #define HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE GENMASK(3, 2) ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6733,6 +6733,9 @@ static void ath11k_mac_op_tx(struct ieee - - if (ar->ab->nss.enabled) - ret = ath11k_nss_tx(arvif, skb); -+ else if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP && 0) -+ ret = ath11k_dp_tx_simple(ar, arvif, skb, -+ (control->sta) ? (struct ath11k_sta *)control->sta->drv_priv : NULL); - else - ret = ath11k_dp_tx(ar, arvif, arsta, skb); - diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch b/package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch deleted file mode 100644 index ffae27277d..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/911-335-ath11k-fix-ar-ops-crash.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Karthikeyan Periyasamy -Subject: [patch] ath11k: fix NULL pointer crash due to the radio ops - -Mac80211 callback ops variable not intialised in the radio structure. -when the firmware not advertise the WMI_TLV_SERVICE_PEER_TID_CONFIGS_SUPPORT -in the service bitmmap, driver try to set set_tid_config ops as NULL. -Since ar->ops already NULL, it leads to NULL pointer access crash. -So fix this crash by properly intialise the mac80211 callback ops -in the radio structure. - -Tested-on: QCN6122 hw1.0 WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1 - -Signed-off-by: Karthikeyan Periyasamy ---- - ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -10558,6 +10558,7 @@ int ath11k_mac_allocate(struct ath11k_ba - struct ieee80211_hw *hw; - struct ath11k *ar; - struct ath11k_pdev *pdev; -+ struct ieee80211_ops *ops; - int ret; - int i; - -@@ -10565,17 +10566,25 @@ int ath11k_mac_allocate(struct ath11k_ba - return 0; - - for (i = 0; i < ab->num_radios; i++) { -+ ops = kmemdup(&ath11k_ops, sizeof(ath11k_ops), GFP_KERNEL); -+ if (!ops) { -+ ret = -ENOMEM; -+ goto err_free_mac; -+ } -+ - pdev = &ab->pdevs[i]; -- hw = ieee80211_alloc_hw(sizeof(struct ath11k), &ath11k_ops); -+ hw = ieee80211_alloc_hw(sizeof(struct ath11k), ops); - if (!hw) { - ath11k_warn(ab, "failed to allocate mac80211 hw device\n"); - ret = -ENOMEM; -+ kfree(ops); - goto err_free_mac; - } - - ar = hw->priv; - ar->hw = hw; - ar->ab = ab; -+ ar->ops = ops; - ar->pdev = pdev; - ar->pdev_idx = i; - ar->lmac_id = ath11k_hw_get_mac_from_pdev_id(&ab->hw_params, i); -@@ -10636,6 +10645,7 @@ void ath11k_mac_destroy(struct ath11k_ba - { - struct ath11k *ar; - struct ath11k_pdev *pdev; -+ struct ieee80211_ops *ops; - int i; - - for (i = 0; i < ab->num_radios; i++) { -@@ -10644,8 +10654,9 @@ void ath11k_mac_destroy(struct ath11k_ba - if (!ar) - continue; - -- ath11k_fw_stats_free(&ar->fw_stats); -+ ops = ar->ops; - ieee80211_free_hw(ar->hw); -+ kfree(ops); - pdev->ar = NULL; - } - } diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch b/package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch deleted file mode 100644 index 8e60a5f6b2..0000000000 --- a/package/kernel/mac80211/patches/ath11k_nss/913-726-mac80211-fix-crash-when-accessing-null-pointer.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 376306e1018974ded893d8fefb91fe69676392d9 Mon Sep 17 00:00:00 2001 -From: Karthikeyan Kathirvel -Date: Mon, 1 May 2023 15:15:56 +0530 -Subject: [PATCH] mac80211: fix crash when accessing null pointer - -During MLD transmission, band will be zero, fetching 0th sband will be an -invalid accessing of sband information and also facing crash when 2ghz -radio is in different phy and other bands are in a single phy, this is -due to 2.4 Ghz sband will be NULL for the phy which is having sbands other -than 2.4 Ghz. - -Fix this by adding sband NULL check. - -[ 2125.764601] Unable to handle kernel read from unreadable memory at virtual address 0000000000000050 -[ 2125.764631] Mem abort info: -[ 2125.772445] ESR = 0x96000005 -[ 2125.775221] EC = 0x25: DABT (current EL), IL = 32 bits -[ 2125.778339] SET = 0, FnV = 0 -[ 2125.783804] EA = 0, S1PTW = 0 -[ 2125.786669] Data abort info: -[ 2125.789707] ISV = 0, ISS = 0x00000005 -[ 2125.792833] CM = 0, WnR = 0 -[ 2125.796394] user pgtable: 4k pages, 39-bit VAs, pgdp=000000006432b000 -[ 2125.799520] [0000000000000050] pgd=0000000000000000, pud=0000000000000000 -[ 2125.805946] Internal error: Oops: 96000005 [#1] PREEMPT SMP -[ 2126.082240] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.213 #0 -[ 2126.110546] pstate: 40400005 (nZcv daif +PAN -UAO) -[ 2126.117591] pc : ieee80211_tx_monitor+0x1ac/0x5d0 [mac80211] -[ 2126.122360] lr : ieee80211_tx_monitor+0x14c/0x5d0 [mac80211] -[ 2126.128163] sp : ffffff803e14ecc0 -[ 2126.133803] x29: ffffff803e14ecc0 x28: 000000000000000d -[ 2126.137016] x27: 0000000000000000 x26: ffffff803892aa40 -[ 2126.142398] x25: 0000000000000009 x24: 0000000000000000 -[ 2126.147694] x23: 0000000000000001 x22: ffffff80250210e0 -[ 2126.152988] x21: ffffff803a0a5800 x20: ffffff803a0a5828 -[ 2126.158284] x19: ffffff803892aa33 x18: 0000000000000000 -[ 2126.163579] x17: 0000000000000000 x16: 0000000000000000 -[ 2126.168873] x15: 0000000000000000 x14: 020101f0fd8c13dd -[ 2126.174169] x13: 00c0bf3d2d200706 x12: 3809ff36b83b03ff -[ 2126.179464] x11: 0a5802c3fe1802c3 x10: 002f3262005e4342 -[ 2126.184759] x9 : 0000a4270000a403 x8 : ffffff803892aa3f -[ 2126.190055] x7 : 0000000000000000 x6 : 0000000000000001 -[ 2126.195349] x5 : ffffff803e14edd8 x4 : 0000000000000001 -[ 2126.200644] x3 : 000000000000000c x2 : 0000000000000000 -[ 2126.205939] x1 : ffffff803892aa3b x0 : 0000000000000040 -[ 2126.211235] Call trace: -[ 2126.216542] ieee80211_tx_monitor+0x1ac/0x5d0 [mac80211] -[ 2126.218714] ieee80211_tx_status_ext+0x78c/0x7d0 [mac80211] -[ 2126.224269] ieee80211_tx_status+0x78/0xa0 [mac80211] -[ 2126.229564] ieee80211_restart_hw+0xe0/0x26c [mac80211] -[ 2126.234763] tasklet_action_common.isra.2+0xa4/0x11c -[ 2126.239795] tasklet_action+0x24/0x2c -[ 2126.245002] __do_softirq+0x10c/0x244 -[ 2126.248561] irq_exit+0x64/0xb4 -[ 2126.252207] __handle_domain_irq+0x88/0xac -[ 2126.255158] gic_handle_irq+0x74/0xbc -[ 2126.259325] el1_irq+0xf0/0x1c0 -[ 2126.263058] arch_cpu_idle+0x10/0x18 -[ 2126.266009] do_idle+0x104/0x248 -[ 2126.269827] cpu_startup_entry+0x20/0x64 -[ 2126.273041] rest_init+0xd0/0xdc -[ 2126.276947] arch_call_rest_init+0xc/0x14 -[ 2126.280159] start_kernel+0x46c/0x4a4 -[ 2126.284070] Code: d37d0863 8b030042 52800183 f9449c42 (f9402842) -[ 2126.287713] ---[ end trace 04f5d203895d53da ]--- - -Signed-off-by: Karthikeyan Kathirvel ---- - net/mac80211/status.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -336,8 +336,11 @@ ieee80211_add_tx_radiotap_header(struct - struct ieee80211_supported_band *sband; - - sband = local->hw.wiphy->bands[info->band]; -- legacy_rate = -- sband->bitrates[info->status.rates[0].idx].bitrate; -+ //TODO: Incase of MLD, band will be 0 for tx pkts -+ //this has to be taken care during TX monitor support. -+ if (sband) -+ legacy_rate = -+ sband->bitrates[info->status.rates[0].idx].bitrate; - } - - if (legacy_rate) { diff --git a/package/kernel/mac80211/patches/nss/ath10k/199-004-ath10k-fixup-nss-compile.patch b/package/kernel/mac80211/patches/nss/ath10k/199-004-ath10k-fixup-nss-compile.patch new file mode 100644 index 0000000000..d413514144 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath10k/199-004-ath10k-fixup-nss-compile.patch @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -5530,7 +5530,7 @@ static int ath10k_mac_set_txbf_conf(stru + ar->wmi.vdev_param->txbf, value); + } + +-static void ath10k_update_vif_offload(struct ieee80211_hw *hw, ++static int ath10k_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) + { + struct ath10k_vif *arvif = (void *)vif->drv_priv; +@@ -5552,6 +5552,7 @@ static void ath10k_update_vif_offload(st + ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", + arvif->vdev_id, ret); + } ++ return ret; + } + + /* diff --git a/package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch b/package/kernel/mac80211/patches/nss/ath11k/033-ath11k-fix-for-peer-memory-corruption.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/033-ath11k-fix-for-peer-memory-corruption.patch rename to package/kernel/mac80211/patches/nss/ath11k/033-ath11k-fix-for-peer-memory-corruption.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch similarity index 84% rename from package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch rename to package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch index d3ffa5bd8d..e4ac1ee17b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/907-068-ath11k-add-rx-histogram-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/068-ath11k-add-rx-histogram-stats.patch @@ -20,7 +20,7 @@ Signed-off-by: Manikanta Pubbisetty --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -44,6 +44,8 @@ +@@ -41,6 +41,8 @@ #define ATH11K_INVALID_HW_MAC_ID 0xFF #define ATH11K_CONNECTION_LOSS_HZ (3 * HZ) @@ -29,7 +29,7 @@ Signed-off-by: Manikanta Pubbisetty /* SMBIOS type containing Board Data File Name Extension */ #define ATH11K_SMBIOS_BDF_EXT_TYPE 0xF8 -@@ -420,6 +422,17 @@ struct ath11k_vif_iter { +@@ -376,6 +378,17 @@ struct ath11k_vif_iter { struct ath11k_vif *arvif; }; @@ -47,7 +47,7 @@ Signed-off-by: Manikanta Pubbisetty struct ath11k_rx_peer_stats { u64 num_msdu; u64 num_mpdu_fcs_ok; -@@ -431,10 +444,6 @@ struct ath11k_rx_peer_stats { +@@ -387,10 +400,6 @@ struct ath11k_rx_peer_stats { u64 non_ampdu_msdu_count; u64 stbc_count; u64 beamformed_count; @@ -58,7 +58,7 @@ Signed-off-by: Manikanta Pubbisetty u64 coding_count[HAL_RX_SU_MU_CODING_MAX]; u64 tid_count[IEEE80211_NUM_TIDS + 1]; u64 pream_cnt[HAL_RX_PREAMBLE_MAX]; -@@ -442,6 +451,8 @@ struct ath11k_rx_peer_stats { +@@ -398,6 +407,8 @@ struct ath11k_rx_peer_stats { u64 rx_duration; u64 dcm_count; u64 ru_alloc_cnt[HAL_RX_RU_ALLOC_TYPE_MAX]; @@ -76,8 +76,8 @@ Signed-off-by: Manikanta Pubbisetty +#include "dp_rx.h" #include "debugfs_htt_stats.h" - static inline u32 ath11k_he_tones_in_ru_to_nl80211_he_ru_alloc(u16 ru_tones) -@@ -390,8 +391,14 @@ static ssize_t ath11k_dbg_sta_dump_rx_st + void ath11k_debugfs_sta_add_tx_stats(struct ath11k_sta *arsta, +@@ -247,8 +248,14 @@ static ssize_t ath11k_dbg_sta_dump_rx_st struct ath11k *ar = arsta->arvif->ar; struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; int len = 0, i, retval = 0; @@ -93,7 +93,7 @@ Signed-off-by: Manikanta Pubbisetty if (!rx_stats) return -ENOENT; -@@ -422,14 +429,6 @@ static ssize_t ath11k_dbg_sta_dump_rx_st +@@ -279,14 +286,6 @@ static ssize_t ath11k_dbg_sta_dump_rx_st rx_stats->num_mpdu_fcs_ok); len += scnprintf(buf + len, size - len, "Num of MPDUs with FCS error: %llu\n", rx_stats->num_mpdu_fcs_err); @@ -108,7 +108,7 @@ Signed-off-by: Manikanta Pubbisetty len += scnprintf(buf + len, size - len, "BCC %llu LDPC %llu\n", rx_stats->coding_count[0], rx_stats->coding_count[1]); len += scnprintf(buf + len, size - len, -@@ -444,14 +443,96 @@ static ssize_t ath11k_dbg_sta_dump_rx_st +@@ -301,14 +300,96 @@ static ssize_t ath11k_dbg_sta_dump_rx_st len += scnprintf(buf + len, size - len, "TID(0-15) Legacy TID(16):"); for (i = 0; i <= IEEE80211_NUM_TIDS; i++) len += scnprintf(buf + len, size - len, "%llu ", rx_stats->tid_count[i]); @@ -212,9 +212,64 @@ Signed-off-by: Manikanta Pubbisetty len += scnprintf(buf + len, size - len, "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0], +@@ -847,6 +928,40 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++static ssize_t ath11k_dbg_sta_reset_rx_stats(struct file *file, ++ const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ieee80211_sta *sta = file->private_data; ++ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; ++ struct ath11k *ar = arsta->arvif->ar; ++ int ret, reset; ++ ++ if (!arsta->rx_stats) ++ return -ENOENT; ++ ++ ret = kstrtoint_from_user(buf, count, 0, &reset); ++ if (ret) ++ return ret; ++ ++ if (!reset || reset > 1) ++ return -EINVAL; ++ ++ spin_lock_bh(&ar->ab->base_lock); ++ memset(arsta->rx_stats, 0, sizeof(*arsta->rx_stats)); ++ spin_unlock_bh(&ar->ab->base_lock); ++ ++ ret = count; ++ return ret; ++} ++ ++static const struct file_operations fops_reset_rx_stats = { ++ .write = ath11k_dbg_sta_reset_rx_stats, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ + void ath11k_debugfs_sta_op_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct dentry *dir) + { +@@ -855,9 +970,12 @@ void ath11k_debugfs_sta_op_add(struct ie + if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) + debugfs_create_file("tx_stats", 0400, dir, sta, + &fops_tx_stats); +- if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) { + debugfs_create_file("rx_stats", 0400, dir, sta, + &fops_rx_stats); ++ debugfs_create_file("reset_rx_stats", 0600, dir, sta, ++ &fops_reset_rx_stats); ++ } + + debugfs_create_file("htt_peer_stats", 0400, dir, sta, + &fops_htt_peer_stats); --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3400,10 +3400,43 @@ exit: +@@ -2762,10 +2762,43 @@ exit: return total_msdu_reaped; } @@ -258,7 +313,7 @@ Signed-off-by: Manikanta Pubbisetty u32 num_msdu; int i; -@@ -3413,6 +3446,8 @@ static void ath11k_dp_rx_update_peer_sta +@@ -2775,6 +2808,8 @@ static void ath11k_dp_rx_update_peer_sta arsta->rssi_comb = ppdu_info->rssi_comb; ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb); @@ -267,7 +322,7 @@ Signed-off-by: Manikanta Pubbisetty num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count + ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count; -@@ -3429,18 +3464,6 @@ static void ath11k_dp_rx_update_peer_sta +@@ -2791,18 +2826,6 @@ static void ath11k_dp_rx_update_peer_sta ppdu_info->tid = IEEE80211_NUM_TIDS; } @@ -286,7 +341,7 @@ Signed-off-by: Manikanta Pubbisetty if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX) rx_stats->coding_count[ppdu_info->ldpc] += num_msdu; -@@ -3469,8 +3492,6 @@ static void ath11k_dp_rx_update_peer_sta +@@ -2831,8 +2854,6 @@ static void ath11k_dp_rx_update_peer_sta rx_stats->dcm_count += ppdu_info->dcm; rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; @@ -295,7 +350,7 @@ Signed-off-by: Manikanta Pubbisetty BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); -@@ -3479,6 +3500,52 @@ static void ath11k_dp_rx_update_peer_sta +@@ -2841,6 +2862,52 @@ static void ath11k_dp_rx_update_peer_sta rx_stats->rx_duration += ppdu_info->rx_duration; arsta->rx_duration = rx_stats->rx_duration; @@ -350,7 +405,7 @@ Signed-off-by: Manikanta Pubbisetty static struct sk_buff *ath11k_dp_rx_alloc_mon_status_buf(struct ath11k_base *ab, --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h -@@ -69,6 +69,25 @@ struct ath11k_dp_rfc1042_hdr { +@@ -41,6 +41,25 @@ struct ath11k_dp_rfc1042_hdr { __be16 snap_type; } __packed; @@ -373,12 +428,12 @@ Signed-off-by: Manikanta Pubbisetty + return ret; +} + - int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, + int ath11k_dp_rx_ampdu_start(struct ath11k *ar, struct ieee80211_ampdu_params *params); - int ath11k_dp_rx_ampdu_stop(struct ath11k_vif *arvif, + int ath11k_dp_rx_ampdu_stop(struct ath11k *ar, --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c -@@ -978,44 +978,78 @@ ath11k_hal_rx_parse_mon_status_tlv(struc +@@ -975,44 +975,78 @@ ath11k_hal_rx_parse_mon_status_tlv(struc ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC, info1); ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1); @@ -481,7 +536,7 @@ Signed-off-by: Manikanta Pubbisetty ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; break; } -@@ -1473,6 +1507,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc +@@ -1470,6 +1504,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc peer_id = ath11k_hal_rx_mpduinfo_get_peerid(ab, mpdu_info); if (peer_id) ppdu_info->peer_id = peer_id; @@ -505,7 +560,7 @@ Signed-off-by: Manikanta Pubbisetty struct hal_rx_mon_status_tlv_hdr { u32 hdr; -@@ -104,6 +108,22 @@ struct hal_rx_user_status { +@@ -103,6 +107,22 @@ struct hal_rx_user_status { u32 mpdu_err_byte_count; }; @@ -528,7 +583,7 @@ Signed-off-by: Manikanta Pubbisetty #define HAL_TLV_STATUS_PPDU_NOT_DONE HAL_RX_MON_STATUS_PPDU_NOT_DONE #define HAL_TLV_STATUS_PPDU_DONE HAL_RX_MON_STATUS_PPDU_DONE #define HAL_TLV_STATUS_BUF_DONE HAL_RX_MON_STATUS_BUF_DONE -@@ -128,6 +148,7 @@ struct hal_rx_mon_ppdu_info { +@@ -127,6 +147,7 @@ struct hal_rx_mon_ppdu_info { u32 num_mpdu_fcs_ok; u32 num_mpdu_fcs_err; u32 preamble_type; @@ -538,7 +593,7 @@ Signed-off-by: Manikanta Pubbisetty u16 tcp_ack_msdu_count; --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -1051,6 +1051,17 @@ static u32 ath11k_hw_wcn6750_get_tcl_rin +@@ -900,6 +900,17 @@ static u32 ath11k_hw_wcn6750_get_tcl_rin return skb_get_hash(skb); } @@ -556,15 +611,15 @@ Signed-off-by: Manikanta Pubbisetty const struct ath11k_hw_ops ipq8074_ops = { .get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id, .wmi_init_config = ath11k_init_wmi_config_ipq8074, -@@ -1089,6 +1100,7 @@ const struct ath11k_hw_ops ipq8074_ops = +@@ -938,6 +949,7 @@ const struct ath11k_hw_ops ipq8074_ops = .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, - #ifdef CPTCFG_ATH11K_MEM_PROFILE_512M - .rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset, - #endif -@@ -1136,6 +1148,7 @@ const struct ath11k_hw_ops ipq6018_ops = + }; + + const struct ath11k_hw_ops ipq6018_ops = { +@@ -978,6 +990,7 @@ const struct ath11k_hw_ops ipq6018_ops = .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, @@ -572,7 +627,7 @@ Signed-off-by: Manikanta Pubbisetty }; const struct ath11k_hw_ops qca6390_ops = { -@@ -1177,6 +1190,7 @@ const struct ath11k_hw_ops qca6390_ops = +@@ -1018,6 +1031,7 @@ const struct ath11k_hw_ops qca6390_ops = .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, @@ -580,15 +635,23 @@ Signed-off-by: Manikanta Pubbisetty }; const struct ath11k_hw_ops qcn9074_ops = { -@@ -1217,6 +1231,7 @@ const struct ath11k_hw_ops qcn9074_ops = - .reo_setup = ath11k_hw_ipq8074_reo_setup, - .mpdu_info_get_peerid = ath11k_hw_qcn9074_mpdu_info_get_peerid, +@@ -1058,6 +1072,7 @@ const struct ath11k_hw_ops qcn9074_ops = + .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, ++ .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len, + }; + + const struct ath11k_hw_ops wcn6855_ops = { +@@ -1098,6 +1113,7 @@ const struct ath11k_hw_ops wcn6855_ops = + .rx_desc_mac_addr2_valid = ath11k_hw_wcn6855_rx_desc_mac_addr2_valid, + .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, }; - const struct ath11k_hw_ops wcn6855_ops = { -@@ -1339,6 +1354,7 @@ const struct ath11k_hw_ops ipq5018_ops = + const struct ath11k_hw_ops wcn6750_ops = { +@@ -1179,6 +1195,7 @@ const struct ath11k_hw_ops ipq5018_ops = .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, @@ -598,11 +661,11 @@ Signed-off-by: Manikanta Pubbisetty #define ATH11K_TX_RING_MASK_0 BIT(0) --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -315,6 +315,7 @@ struct ath11k_hw_ops { +@@ -269,6 +269,7 @@ struct ath11k_hw_ops { bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); u32 (*get_ring_selector)(struct sk_buff *skb); + u32 (*rx_desc_get_hal_mpdu_len)(struct hal_rx_mpdu_info *mpdu_info); - #ifdef CPTCFG_ATH11K_MEM_PROFILE_512M - void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter); - #endif + }; + + extern const struct ath11k_hw_ops ipq8074_ops; diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/069-ath11k-add-HE-stats-in-peer-stats.patch similarity index 93% rename from package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch rename to package/kernel/mac80211/patches/nss/ath11k/069-ath11k-add-HE-stats-in-peer-stats.patch index 4831424fa4..5c29297c33 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-069-ath11k-add-HE-stats-in-peer-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/069-ath11k-add-HE-stats-in-peer-stats.patch @@ -20,10 +20,10 @@ Signed-off-by: Miles Hu #include "spectral.h" #include "wow.h" +#include "rx_desc.h" - #include "nss.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -476,6 +477,8 @@ struct ath11k_htt_data_stats { + +@@ -469,6 +470,8 @@ struct ath11k_htt_data_stats { u64 bw[ATH11K_COUNTER_TYPE_MAX][ATH11K_BW_NUM]; u64 nss[ATH11K_COUNTER_TYPE_MAX][ATH11K_NSS_NUM]; u64 gi[ATH11K_COUNTER_TYPE_MAX][ATH11K_GI_NUM]; @@ -32,7 +32,7 @@ Signed-off-by: Miles Hu }; struct ath11k_htt_tx_stats { -@@ -483,6 +486,9 @@ struct ath11k_htt_tx_stats { +@@ -476,6 +479,9 @@ struct ath11k_htt_tx_stats { u64 tx_duration; u64 ba_fails; u64 ack_fails; @@ -42,7 +42,7 @@ Signed-off-by: Miles Hu }; struct ath11k_per_ppdu_tx_stats { -@@ -615,11 +621,16 @@ struct ath11k_per_peer_tx_stats { +@@ -592,11 +598,16 @@ struct ath11k_per_peer_tx_stats { u32 succ_bytes; u32 retry_bytes; u32 failed_bytes; @@ -62,8 +62,8 @@ Signed-off-by: Miles Hu --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c -@@ -12,13 +12,39 @@ - #include "dp_tx.h" +@@ -13,13 +13,39 @@ + #include "dp_rx.h" #include "debugfs_htt_stats.h" +static inline u32 ath11k_he_tones_in_ru_to_nl80211_he_ru_alloc(u16 ru_tones) @@ -103,7 +103,7 @@ Signed-off-by: Miles Hu if (!arsta->tx_stats) return; -@@ -63,6 +89,43 @@ void ath11k_debugfs_sta_add_tx_stats(str +@@ -64,6 +90,43 @@ void ath11k_debugfs_sta_add_tx_stats(str STATS_OP_FMT(RETRY).legacy[1][mcs] += peer_stats->retry_pkts; } @@ -147,7 +147,7 @@ Signed-off-by: Miles Hu if (peer_stats->is_ampdu) { tx_stats->ba_fails += peer_stats->ba_fails; -@@ -123,6 +186,17 @@ void ath11k_debugfs_sta_add_tx_stats(str +@@ -124,6 +187,17 @@ void ath11k_debugfs_sta_add_tx_stats(str STATS_OP_FMT(RETRY).gi[1][gi] += peer_stats->retry_pkts; tx_stats->tx_duration += peer_stats->duration; @@ -165,7 +165,7 @@ Signed-off-by: Miles Hu } void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar, -@@ -139,12 +213,13 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -140,12 +214,13 @@ static ssize_t ath11k_dbg_sta_dump_tx_st struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; struct ath11k_htt_data_stats *stats; @@ -179,9 +179,9 @@ Signed-off-by: Miles Hu + char *buf, mu_group_id[MAX_MU_GROUP_LENGTH] = {0}; + u32 index; - buf = kzalloc(size, GFP_KERNEL); - if (!buf) -@@ -165,45 +240,46 @@ static ssize_t ath11k_dbg_sta_dump_tx_st + if (!arsta->tx_stats) + return -ENOENT; +@@ -163,45 +238,46 @@ static ssize_t ath11k_dbg_sta_dump_tx_st len += scnprintf(buf + len, size - len, "%s_%s\n", str_name[k], str[j]); @@ -237,7 +237,7 @@ Signed-off-by: Miles Hu stats->gi[j][0], stats->gi[j][1], stats->gi[j][2], stats->gi[j][3]); len += scnprintf(buf + len, size - len, -@@ -212,10 +288,68 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -210,10 +286,68 @@ static ssize_t ath11k_dbg_sta_dump_tx_st for (i = 0; i < ATH11K_LEGACY_NUM; i++) len += scnprintf(buf + len, size - len, "%llu ", stats->legacy[j][i]); @@ -307,7 +307,7 @@ Signed-off-by: Miles Hu len += scnprintf(buf + len, size - len, "\nTX duration\n %llu usecs\n", arsta->tx_stats->tx_duration); -@@ -223,6 +357,7 @@ static ssize_t ath11k_dbg_sta_dump_tx_st +@@ -221,6 +355,7 @@ static ssize_t ath11k_dbg_sta_dump_tx_st "BA fails\n %llu\n", arsta->tx_stats->ba_fails); len += scnprintf(buf + len, size - len, "ack fails\n %llu\n", arsta->tx_stats->ack_fails); @@ -317,7 +317,7 @@ Signed-off-by: Miles Hu if (len > size) --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -598,6 +598,45 @@ enum htt_ppdu_stats_tag_type { +@@ -595,6 +595,45 @@ enum htt_ppdu_stats_tag_type { BIT(HTT_PPDU_STATS_TAG_TX_MGMTCTRL_PAYLOAD) | \ HTT_PPDU_STATS_TAG_DEFAULT) @@ -363,7 +363,7 @@ Signed-off-by: Miles Hu /* HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG Message * * details: -@@ -1315,6 +1354,19 @@ enum htt_ppdu_stats_gi { +@@ -1234,6 +1273,19 @@ enum htt_ppdu_stats_gi { #define HTT_PPDU_STATS_USER_RATE_INFO0_USER_POS_M GENMASK(3, 0) #define HTT_PPDU_STATS_USER_RATE_INFO0_MU_GROUP_ID_M GENMASK(11, 4) @@ -383,7 +383,7 @@ Signed-off-by: Miles Hu #define HTT_PPDU_STATS_USER_RATE_INFO1_RESP_TYPE_VALD_M BIT(0) #define HTT_PPDU_STATS_USER_RATE_INFO1_PPDU_TYPE_M GENMASK(5, 1) -@@ -1342,6 +1394,12 @@ enum htt_ppdu_stats_gi { +@@ -1261,6 +1313,12 @@ enum htt_ppdu_stats_gi { FIELD_GET(HTT_PPDU_STATS_USER_RATE_FLAGS_GI_M, _val) #define HTT_USR_RATE_DCM(_val) \ FIELD_GET(HTT_PPDU_STATS_USER_RATE_FLAGS_DCM_M, _val) @@ -396,7 +396,7 @@ Signed-off-by: Miles Hu #define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_LTF_SIZE_M GENMASK(1, 0) #define HTT_PPDU_STATS_USER_RATE_RESP_FLAGS_STBC_M BIT(2) -@@ -1445,6 +1503,21 @@ struct htt_ppdu_stats_usr_cmpltn_ack_ba_ +@@ -1364,6 +1422,21 @@ struct htt_ppdu_stats_usr_cmpltn_ack_ba_ u32 success_bytes; } __packed; @@ -418,7 +418,7 @@ Signed-off-by: Miles Hu struct htt_ppdu_stats_usr_cmn_array { struct htt_tlv tlv_hdr; u32 num_ppdu_stats; -@@ -1458,14 +1531,16 @@ struct htt_ppdu_stats_usr_cmn_array { +@@ -1377,14 +1450,16 @@ struct htt_ppdu_stats_usr_cmn_array { struct htt_ppdu_user_stats { u16 peer_id; @@ -436,7 +436,7 @@ Signed-off-by: Miles Hu #define HTT_PPDU_DESC_MAX_DEPTH 16 struct htt_ppdu_stats { -@@ -1474,7 +1549,7 @@ struct htt_ppdu_stats { +@@ -1393,7 +1468,7 @@ struct htt_ppdu_stats { }; struct htt_ppdu_stats_info { @@ -447,7 +447,7 @@ Signed-off-by: Miles Hu }; --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1319,9 +1319,10 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1252,9 +1252,10 @@ static int ath11k_htt_tlv_ppdu_stats_par void *data) { struct htt_ppdu_stats_info *ppdu_info; @@ -459,7 +459,7 @@ Signed-off-by: Miles Hu ppdu_info = data; -@@ -1334,6 +1335,26 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1267,6 +1268,26 @@ static int ath11k_htt_tlv_ppdu_stats_par } memcpy((void *)&ppdu_info->ppdu_stats.common, ptr, sizeof(struct htt_ppdu_stats_common)); @@ -486,7 +486,7 @@ Signed-off-by: Miles Hu break; case HTT_PPDU_STATS_TAG_USR_RATE: if (len < sizeof(struct htt_ppdu_stats_user_rate)) { -@@ -1366,6 +1387,7 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1299,6 +1320,7 @@ static int ath11k_htt_tlv_ppdu_stats_par peer_id); if (cur_user < 0) return -EINVAL; @@ -494,7 +494,7 @@ Signed-off-by: Miles Hu user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user]; user_stats->peer_id = peer_id; user_stats->is_valid_peer_id = true; -@@ -1394,44 +1416,30 @@ static int ath11k_htt_tlv_ppdu_stats_par +@@ -1327,44 +1349,30 @@ static int ath11k_htt_tlv_ppdu_stats_par sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); user_stats->tlv_flags |= BIT(tag); break; @@ -559,7 +559,7 @@ Signed-off-by: Miles Hu return 0; } -@@ -1449,8 +1457,8 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1382,8 +1390,8 @@ ath11k_update_per_peer_tx_stats(struct a struct htt_ppdu_stats_common *common = &ppdu_stats->common; int ret; u8 flags, mcs, nss, bw, sgi, dcm, rate_idx = 0; @@ -570,7 +570,7 @@ Signed-off-by: Miles Hu u32 tx_duration = 0; u8 tid = HTT_PPDU_STATS_NON_QOS_TID; bool is_ampdu = false; -@@ -1481,6 +1489,11 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1414,6 +1422,11 @@ ath11k_update_per_peer_tx_stats(struct a mcs = HTT_USR_RATE_MCS(user_rate->rate_flags); sgi = HTT_USR_RATE_GI(user_rate->rate_flags); dcm = HTT_USR_RATE_DCM(user_rate->rate_flags); @@ -582,7 +582,7 @@ Signed-off-by: Miles Hu /* Note: If host configured fixed rates and in some other special * cases, the broadcast/management frames are sent in different rates. -@@ -1575,6 +1588,12 @@ ath11k_update_per_peer_tx_stats(struct a +@@ -1508,6 +1521,12 @@ ath11k_update_per_peer_tx_stats(struct a peer_stats->ba_fails = HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) + HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags); @@ -595,7 +595,7 @@ Signed-off-by: Miles Hu if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); -@@ -1627,13 +1646,87 @@ struct htt_ppdu_stats_info *ath11k_dp_ht +@@ -1560,13 +1579,89 @@ struct htt_ppdu_stats_info *ath11k_dp_ht return ppdu_info; } @@ -640,8 +640,10 @@ Signed-off-by: Miles Hu + int ret = -EINVAL; + struct htt_ppdu_stats_info * ppdu_info = NULL; + -+ ppdu_info = (struct htt_ppdu_stats_info *)data; -+ ppdu_info->tlv_bitmap = 0; ++ if (data) { ++ ppdu_info = (struct htt_ppdu_stats_info *)data; ++ ppdu_info->tlv_bitmap = 0; ++ } + while (len > 0) { + if (len < sizeof(*tlv)) { + ath11k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", @@ -684,7 +686,7 @@ Signed-off-by: Miles Hu u8 pdev_id; u32 ppdu_id, len; -@@ -1668,6 +1761,47 @@ static int ath11k_htt_pull_ppdu_stats(st +@@ -1601,6 +1696,47 @@ static int ath11k_htt_pull_ppdu_stats(st goto out_unlock_data; } @@ -734,7 +736,7 @@ Signed-off-by: Miles Hu --- a/drivers/net/wireless/ath/ath11k/rx_desc.h +++ b/drivers/net/wireless/ath/ath11k/rx_desc.h -@@ -1500,6 +1500,11 @@ struct hal_rx_desc { +@@ -1494,6 +1494,11 @@ struct hal_rx_desc { } u; } __packed; @@ -748,9 +750,9 @@ Signed-off-by: Miles Hu #define RU_52 2 --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -48,6 +48,17 @@ struct ath11k_ast_entry { - struct list_head ase_list; - }; +@@ -7,6 +7,17 @@ + #ifndef ATH11K_PEER_H + #define ATH11K_PEER_H +struct ppdu_user_delayba { + u8 reserved0; @@ -766,7 +768,7 @@ Signed-off-by: Miles Hu struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -83,6 +94,8 @@ struct ath11k_peer { +@@ -36,6 +47,8 @@ struct ath11k_peer { u16 sec_type_grp; bool is_authorized; bool dp_setup_done; diff --git a/package/kernel/mac80211/patches/nss/ath11k/080-ath11k-ethernet-rx-decap-offload.patch b/package/kernel/mac80211/patches/nss/ath11k/080-ath11k-ethernet-rx-decap-offload.patch new file mode 100644 index 0000000000..3334ef52f8 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/080-ath11k-ethernet-rx-decap-offload.patch @@ -0,0 +1,15 @@ +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -27,10 +27,10 @@ module_param_named(crypto_mode, ath11k_c + MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software"); + + /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */ +-unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI; ++unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_ETHERNET; + module_param_named(frame_mode, ath11k_frame_mode, uint, 0644); + MODULE_PARM_DESC(frame_mode, +- "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); ++ "Datapath frame mode (0: raw, 1: native wifi, 2: ethernet(default))"); + + bool ath11k_ftm_mode; + module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444); diff --git a/package/kernel/mac80211/patches/nss/ath11k/084-ath11k-fix-ul-ofdma-counter-always-zero-in-peer-stat.patch b/package/kernel/mac80211/patches/nss/ath11k/084-ath11k-fix-ul-ofdma-counter-always-zero-in-peer-stat.patch new file mode 100644 index 0000000000..b46a32c092 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/084-ath11k-fix-ul-ofdma-counter-always-zero-in-peer-stat.patch @@ -0,0 +1,82 @@ +From 3827a38706dcf081992fccf30957b29e81a25e5c Mon Sep 17 00:00:00 2001 +From: Miles Hu +Date: Mon, 25 Nov 2019 10:24:41 -0800 +Subject: [PATCH] ath11k: fix ul-ofdma counter always zero in peer stats + +The problem is caused by RSSI_LEGACY tlv is not handled properly. +All ul mu receiption information need to be extracted from the tlv. + +Signed-off-by: Miles Hu +--- + drivers/net/wireless/ath/ath11k/debugfs_sta.c | 7 ------- + drivers/net/wireless/ath/ath11k/hal_rx.c | 17 +++++++++++++++++ + drivers/net/wireless/ath/ath11k/hal_rx.h | 8 ++++++++ + 3 files changed, 25 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -525,13 +525,6 @@ static ssize_t ath11k_dbg_sta_dump_rx_st + rx_stats->byte_stats.rx_rate[i], + (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); + +- len += scnprintf(buf + len, size - len, +- "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", +- rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0], +- rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2], +- rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4], +- rx_stats->ru_alloc_cnt[5]); +- + len += scnprintf(buf + len, size - len, "\n"); + + spin_unlock_bh(&ar->ab->base_lock); +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -1478,6 +1478,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ab->wmi_ab.svc_map); + struct hal_rx_phyrx_rssi_legacy_info *rssi = + (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data; ++ u32 reception_type = 0; + + /* TODO: Please note that the combined rssi will not be accurate + * in MU case. Rssi in MU needs to be retrieved from +@@ -1487,6 +1488,22 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB, + __le32_to_cpu(rssi->info0)); + ++ reception_type = ++ FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_RSVD1_RECEPTION, ++ __le32_to_cpu(rssi->rsvd[0])); ++ ++ switch (reception_type) { ++ case HAL_RECEPTION_TYPE_ULOFMDA: ++ ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA; ++ break; ++ case HAL_RECEPTION_TYPE_ULMIMO: ++ ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO; ++ break; ++ default: ++ ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU; ++ break; ++ } ++ + if (db2dbm) { + for (i = 0; i < ARRAY_SIZE(rssi->preamble); i++) { + ppdu_info->rssi_chain_pri20[i] = +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -414,6 +414,15 @@ struct hal_rx_he_sig_b2_ofdma_info { + + #define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB GENMASK(15, 8) + ++#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_RSVD1_RECEPTION GENMASK(3, 0) ++ ++enum hal_rx_ul_reception_type { ++ HAL_RECEPTION_TYPE_ULOFMDA, ++ HAL_RECEPTION_TYPE_ULMIMO, ++ HAL_RECEPTION_TYPE_OTHER, ++ HAL_RECEPTION_TYPE_FRAMELESS ++}; ++ + #define HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20 GENMASK(7, 0) + + struct hal_rx_phyrx_chain_rssi { diff --git a/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch b/package/kernel/mac80211/patches/nss/ath11k/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch similarity index 91% rename from package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch rename to package/kernel/mac80211/patches/nss/ath11k/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch index 326db09145..52e2509b79 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/087-ath11k-fix-ul-ofdma-counter-increamenting-improperly.patch @@ -5,7 +5,7 @@ --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -5242,8 +5242,11 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -5451,8 +5451,11 @@ int ath11k_dp_rx_process_mon_status(stru goto next_skb; } @@ -33,7 +33,7 @@ __le32_to_cpu(eu_stats->info7))) - 1; --- a/drivers/net/wireless/ath/ath11k/hal_rx.h +++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -@@ -66,6 +66,7 @@ enum hal_rx_reception_type { +@@ -70,6 +70,7 @@ enum hal_rx_reception_type { }; #define HAL_RX_FCS_LEN 4 @@ -41,7 +41,7 @@ enum hal_rx_mon_status { HAL_RX_MON_STATUS_PPDU_NOT_DONE, -@@ -150,6 +151,7 @@ struct hal_rx_mon_ppdu_info { +@@ -171,6 +172,7 @@ struct hal_rx_mon_ppdu_info { u8 rssi_comb; u8 rssi_chain_pri20[HAL_RX_MAX_NSS]; u16 tid; diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch similarity index 91% rename from package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch rename to package/kernel/mac80211/patches/nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch index 9be70411b1..18477cd523 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/907-108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c -@@ -532,6 +532,12 @@ static ssize_t ath11k_dbg_sta_dump_rx_st +@@ -524,6 +524,12 @@ static ssize_t ath11k_dbg_sta_dump_rx_st len += scnprintf(buf + len, size - len, "%10llu%s", rx_stats->byte_stats.rx_rate[i], (i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n"); @@ -11,11 +11,11 @@ + rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4], + rx_stats->ru_alloc_cnt[5]); - len += scnprintf(buf + len, size - len, - "\nDCM: %llu\nRU: 26 %llu 52: %llu 106: %llu 242: %llu 484: %llu 996: %llu\n", + len += scnprintf(buf + len, size - len, "\n"); + --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3236,11 +3236,12 @@ exit: +@@ -2901,11 +2901,12 @@ exit: static void ath11k_dp_rx_update_peer_rate_table_stats(struct ath11k_rx_peer_stats *rx_stats, struct hal_rx_mon_ppdu_info *ppdu_info, @@ -30,7 +30,7 @@ u32 bw_idx = ppdu_info->bw; u32 gi_idx = ppdu_info->gi; -@@ -3262,10 +3263,13 @@ ath11k_dp_rx_update_peer_rate_table_stat +@@ -2927,10 +2928,13 @@ ath11k_dp_rx_update_peer_rate_table_stat } rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu; @@ -46,7 +46,7 @@ struct hal_rx_mon_ppdu_info *ppdu_info) { struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats; -@@ -3323,7 +3327,6 @@ static void ath11k_dp_rx_update_peer_sta +@@ -2988,7 +2992,6 @@ static void ath11k_dp_rx_update_peer_sta rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok; rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err; rx_stats->dcm_count += ppdu_info->dcm; @@ -54,7 +54,7 @@ BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > ARRAY_SIZE(ppdu_info->rssi_chain_pri20)); -@@ -3341,10 +3344,10 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3006,10 +3009,10 @@ static void ath11k_dp_rx_update_peer_sta if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N && ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) { @@ -69,7 +69,7 @@ } if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC && -@@ -3377,7 +3380,120 @@ static void ath11k_dp_rx_update_peer_sta +@@ -3042,7 +3045,120 @@ static void ath11k_dp_rx_update_peer_sta rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len; } @@ -191,7 +191,7 @@ } -@@ -5846,6 +5962,55 @@ static void ath11k_dp_rx_mon_dest_proces +@@ -5380,6 +5496,55 @@ static void ath11k_dp_rx_mon_dest_proces } } @@ -247,20 +247,19 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, struct napi_struct *napi, int budget) { -@@ -5917,10 +6082,13 @@ int ath11k_dp_rx_process_mon_status(stru - goto next_skb; - } +@@ -5453,8 +5618,13 @@ int ath11k_dp_rx_process_mon_status(stru -- if ((ppdu_info->fc_valid) && -- (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { -+ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { - arsta = (struct ath11k_sta *)peer->sta->drv_priv; + if ((ppdu_info->fc_valid) && + (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { +- arsta = (struct ath11k_sta *)peer->sta->drv_priv; - ath11k_dp_rx_update_peer_stats(arsta, ppdu_info); -+ ath11k_dp_rx_update_peer_su_stats(arsta, ppdu_info); -+ } else if ((ppdu_info->fc_valid) && -+ (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) { -+ ath11k_dp_rx_mon_process_ulofdma(ppdu_info); -+ ath11k_dp_rx_update_peer_mu_stats(ar, ppdu_info); ++ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { ++ arsta = (struct ath11k_sta *)peer->sta->drv_priv; ++ ath11k_dp_rx_update_peer_su_stats(arsta, ppdu_info); ++ } else { ++ ath11k_dp_rx_mon_process_ulofdma(ppdu_info); ++ ath11k_dp_rx_update_peer_mu_stats(ar, ppdu_info); ++ } } if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr)) @@ -420,7 +419,7 @@ struct hal_rx_ppdu_start { --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -94,6 +94,20 @@ struct ath11k_peer *ath11k_peer_find_by_ +@@ -93,6 +93,20 @@ struct ath11k_peer *ath11k_peer_find_by_ return NULL; } @@ -438,12 +437,12 @@ + return NULL; +} + - #ifdef CPTCFG_ATH11K_NSS_SUPPORT - struct ath11k_ast_entry *ath11k_peer_ast_find_by_peer(struct ath11k_base *ab, - struct ath11k_peer *peer, + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) + { + struct ath11k_peer *peer; --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -112,6 +112,7 @@ struct ath11k_peer *ath11k_peer_find(str +@@ -59,6 +59,7 @@ struct ath11k_peer *ath11k_peer_find(str struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab, const u8 *addr); struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, int peer_id); diff --git a/package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch b/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch similarity index 92% rename from package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch rename to package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch index 8ef3d9ba7c..2ba2411c3e 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/113-ath11k-add-8023-undecap-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/113-ath11k-add-8023-undecap-support.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2163,6 +2163,42 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2305,6 +2305,42 @@ static void ath11k_dp_rx_h_undecap_eth(s ether_addr_copy(ieee80211_get_SA(hdr), sa); } @@ -43,7 +43,7 @@ static void ath11k_dp_rx_h_undecap(struct ath11k *ar, struct sk_buff *msdu, struct hal_rx_desc *rx_desc, enum hal_encrypt_type enctype, -@@ -2204,7 +2240,8 @@ static void ath11k_dp_rx_h_undecap(struc +@@ -2346,7 +2382,8 @@ static void ath11k_dp_rx_h_undecap(struc enctype, status); break; case DP_RX_DECAP_TYPE_8023: diff --git a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/142-ath11k-adding-support-for-mgmt-frame-stats.patch similarity index 97% rename from package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch rename to package/kernel/mac80211/patches/nss/ath11k/142-ath11k-adding-support-for-mgmt-frame-stats.patch index f1dfc0f7b9..c069cc8ff9 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/142-ath11k-adding-support-for-mgmt-frame-stats.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/142-ath11k-adding-support-for-mgmt-frame-stats.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -311,6 +311,16 @@ struct ath11k_rekey_data { +@@ -314,6 +314,16 @@ struct ath11k_rekey_data { bool enable_offload; }; @@ -17,7 +17,7 @@ struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; -@@ -369,6 +379,8 @@ struct ath11k_vif { +@@ -372,6 +382,8 @@ struct ath11k_vif { #ifdef CPTCFG_ATH11K_DEBUGFS struct dentry *debugfs_twt; #endif /* CPTCFG_ATH11K_DEBUGFS */ @@ -39,7 +39,7 @@ + struct ath11k_vif *arvif = NULL; + struct ath11k_mgmt_frame_stats *mgmt_stats; + int len = 0, ret, i; -+ int size = (TARGET_NUM_VDEVS - 1) * 1500; ++ int size = (TARGET_NUM_VDEVS(ar->ab) - 1) * 1500; + char *buf; + const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX-1] = {"assoc_req", "assoc_resp", + "reassoc_req", "reassoc_resp", @@ -178,7 +178,7 @@ } --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -444,6 +444,7 @@ int ath11k_peer_create(struct ath11k *ar +@@ -458,6 +458,7 @@ int ath11k_peer_create(struct ath11k *ar peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; @@ -188,7 +188,7 @@ arsta = ath11k_sta_to_arsta(sta); --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -10,6 +10,7 @@ +@@ -21,6 +21,7 @@ struct ppdu_user_delayba { struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; @@ -233,7 +233,7 @@ + arvif = ath11k_vif_to_arvif(vif); + mgmt_stats = &arvif->mgmt_stats; + -+ if (!status) ++ if (!tx_compl_param->status) + mgmt_stats->tx_compl_succ[frm_type]++; + else + mgmt_stats->tx_compl_fail[frm_type]++; diff --git a/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch b/package/kernel/mac80211/patches/nss/ath11k/181-ath11k-remove-error-on-soc-debugfs-fail.patch similarity index 88% rename from package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch rename to package/kernel/mac80211/patches/nss/ath11k/181-ath11k-remove-error-on-soc-debugfs-fail.patch index b47785828a..ca21c0b142 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/907-ath11k-remove-error-on-soc-debugfs-fail.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/181-ath11k-remove-error-on-soc-debugfs-fail.patch @@ -34,7 +34,7 @@ Signed-off-by: Anilkumar Kolli --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -2260,5 +2260,17 @@ err_sc_free: +@@ -2189,5 +2189,17 @@ err_sc_free: } EXPORT_SYMBOL(ath11k_core_alloc); @@ -54,16 +54,16 @@ Signed-off-by: Anilkumar Kolli MODULE_LICENSE("Dual BSD/GPL"); --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -15,6 +15,8 @@ +@@ -16,6 +16,8 @@ + #include "peer.h" #include "hif.h" - #include "qmi.h" +struct dentry *debugfs_ath11k; + static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = { "REO2SW1_RING", "REO2SW2_RING", -@@ -1228,8 +1230,6 @@ int ath11k_debugfs_pdev_create(struct at +@@ -991,8 +993,6 @@ int ath11k_debugfs_pdev_create(struct at void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab) { @@ -72,7 +72,7 @@ Signed-off-by: Anilkumar Kolli } int ath11k_debugfs_soc_create(struct ath11k_base *ab) -@@ -1282,6 +1282,24 @@ void ath11k_debugfs_soc_destroy(struct a +@@ -1045,6 +1045,24 @@ void ath11k_debugfs_soc_destroy(struct a } EXPORT_SYMBOL(ath11k_debugfs_soc_destroy); @@ -97,17 +97,7 @@ Signed-off-by: Anilkumar Kolli void ath11k_debugfs_fw_stats_init(struct ath11k *ar) { struct dentry *fwstats_dir = debugfs_create_dir("fw_stats", -@@ -1932,6 +1950,9 @@ void ath11k_debugfs_unregister(struct at - kfree(dbr_debug); - ar->debug.dbr_debug[i] = NULL; - } -+ -+ debugfs_remove_recursive(ar->debug.debugfs_pdev); -+ ar->debug.debugfs_pdev = NULL; - } - - static ssize_t ath11k_write_twt_add_dialog(struct file *file, -@@ -2294,6 +2315,9 @@ int ath11k_debugfs_register(struct ath11 +@@ -1675,6 +1693,9 @@ int ath11k_debugfs_register(struct ath11 char pdev_name[10]; char buf[100] = {0}; @@ -117,10 +107,20 @@ Signed-off-by: Anilkumar Kolli snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx); ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); +@@ -1752,6 +1773,9 @@ void ath11k_debugfs_unregister(struct at + kfree(dbr_debug); + ar->debug.dbr_debug[i] = NULL; + } ++ ++ debugfs_remove_recursive(ar->debug.debugfs_pdev); ++ ar->debug.debugfs_pdev = NULL; + } + + static ssize_t ath11k_write_twt_add_dialog(struct file *file, --- a/drivers/net/wireless/ath/ath11k/debugfs.h +++ b/drivers/net/wireless/ath/ath11k/debugfs.h -@@ -282,6 +282,8 @@ do { \ - #endif +@@ -263,6 +263,8 @@ struct ath11k_fw_dbglog { + }; #ifdef CPTCFG_ATH11K_DEBUGFS +int ath11k_debugfs_create(void); @@ -128,8 +128,8 @@ Signed-off-by: Anilkumar Kolli int ath11k_debugfs_soc_create(struct ath11k_base *ab); void ath11k_debugfs_soc_destroy(struct ath11k_base *ab); int ath11k_debugfs_pdev_create(struct ath11k_base *ab); -@@ -338,6 +340,15 @@ static inline int ath11k_debug_is_memory - } +@@ -314,6 +316,15 @@ void ath11k_debugfs_add_dbring_entry(str + struct hal_srng *srng); #else +static inline int ath11k_debugfs_create(void) diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch b/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch similarity index 84% rename from package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch rename to package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch index 47b29fd19e..1fe5317105 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/906-ath11k-m3-ssr-dump-collection.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/188-ath11k-m3-ssr-dump-collection.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c -@@ -2101,6 +2101,9 @@ static int ath11k_qmi_assign_target_mem_ +@@ -2100,6 +2100,9 @@ static int ath11k_qmi_assign_target_mem_ ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; idx++; break; diff --git a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch b/package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch similarity index 54% rename from package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch rename to package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch index dea5600324..466dacd100 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/191-ath11k-add-mgmt-and-data-ack-rssi.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/191-ath11k-add-mgmt-and-data-ack-rssi.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9571,6 +9571,8 @@ static int __ath11k_mac_register(struct +@@ -9580,6 +9580,8 @@ static int __ath11k_mac_register(struct wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); @@ -19,30 +19,3 @@ wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support; wmi_cfg->sched_params = tg_cfg->sched_params; wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; -@@ -5874,7 +5875,7 @@ static int wmi_process_mgmt_tx_comp(stru - arvif = ath11k_vif_to_arvif(vif); - mgmt_stats = &arvif->mgmt_stats; - -- if (!status) -+ if (!tx_compl_param->status) - mgmt_stats->tx_compl_succ[frm_type]++; - else - mgmt_stats->tx_compl_fail[frm_type]++; ---- a/drivers/net/wireless/ath/ath11k/wmi.h -+++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -4539,6 +4539,7 @@ struct wmi_pdev_bss_chan_info_event { - u32 rx_bss_cycle_count_low; - u32 rx_bss_cycle_count_high; - u32 pdev_id; -+ u32 ack_rssi; - } __packed; - - #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0 -@@ -4890,7 +4891,6 @@ struct wmi_mgmt_tx_compl_event { - u32 desc_id; - u32 status; - u32 pdev_id; -- u32 ppdu_id; - u32 ack_rssi; - } __packed; - diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch b/package/kernel/mac80211/patches/nss/ath11k/199-002-ath11k_nss-add-nss-driver-interface.patch similarity index 99% rename from package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch rename to package/kernel/mac80211/patches/nss/ath11k/199-002-ath11k_nss-add-nss-driver-interface.patch index 79f8190d5b..851e4ed022 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-002-ath11k_nss-add-nss-driver-interface.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-002-ath11k_nss-add-nss-driver-interface.patch @@ -48,7 +48,7 @@ Signed-off-by: Sriram R ath11k_ahb-y += ahb.o --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -0,0 +1,2392 @@ +@@ -0,0 +1,2396 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. @@ -259,8 +259,9 @@ Signed-off-by: Sriram R + peer = ath11k_peer_find_by_id(ab, peer_id); + if (!peer) { + spin_unlock_bh(&ab->base_lock); -+ ath11k_warn(ab, "ath11k_nss: unable to free peer mem, peer_id:%d\n", -+ peer_id); ++ if(ab->nss.debug_mode) ++ ath11k_warn(ab, "ath11k_nss: unable to free peer mem, peer_id:%d\n", ++ peer_id); + return; + } + @@ -675,7 +676,7 @@ Signed-off-by: Sriram R + int encap_type = ath11k_dp_tx_get_encap_type(arvif, skb); + struct ath11k_soc_dp_stats *soc_stats = &ar->ab->soc_stats; + -+ if (!arvif->ar->ab->nss.debug_mode && encap_type != arvif->nss.encap) { ++ if (encap_type != arvif->nss.encap) { + ath11k_warn(ar->ab, "encap mismatch in nss tx skb encap type %d" \ + " vif encap type %d\n", encap_type, arvif->nss.encap); + goto drop; @@ -1421,7 +1422,7 @@ Signed-off-by: Sriram R + */ + ret = wait_for_completion_timeout(&peer->nss.complete, + msecs_to_jiffies(ATH11K_NSS_MSG_TIMEOUT_MS)); -+ if (!ret) ++ if (ab->nss.debug_mode && !ret) + ath11k_warn(ab, "timeout while waiting for nss peer delete msg response\n"); + + return 0; @@ -1764,6 +1765,8 @@ Signed-off-by: Sriram R + return ATH11K_WIFILI_TARGET_TYPE_QCA6018; + case ATH11K_HW_QCN9074_HW10: + return ATH11K_WIFILI_TARGET_TYPE_QCN9074; ++ case ATH11K_HW_IPQ5018_HW10: ++ return ATH11K_WIFILI_TARGET_TYPE_QCA5018; + default: + ath11k_warn(ab, "NSS Offload not supported for this HW\n"); + return ATH11K_WIFILI_TARGET_TYPE_UNKNOWN; @@ -1775,6 +1778,7 @@ Signed-off-by: Sriram R + switch (ab->hw_rev) { + case ATH11K_HW_IPQ8074: + case ATH11K_HW_IPQ6018_HW10: ++ case ATH11K_HW_IPQ5018_HW10: + return NSS_WIFILI_INTERNAL_INTERFACE; + case ATH11K_HW_QCN9074_HW10: + return nss_get_available_wifili_external_if(); @@ -2799,7 +2803,7 @@ Signed-off-by: Sriram R static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset) { struct ath11k_base *ab = ab_pci->ab; -@@ -708,6 +722,7 @@ static const struct ath11k_hif_ops ath11 +@@ -710,6 +724,7 @@ static const struct ath11k_hif_ops ath11 .map_service_to_pipe = ath11k_pcic_map_service_to_pipe, .ce_irq_enable = ath11k_pci_hif_ce_irq_enable, .ce_irq_disable = ath11k_pci_hif_ce_irq_disable, @@ -2979,7 +2983,7 @@ Signed-off-by: Sriram R enum dp_rx_decap_type { DP_RX_DECAP_TYPE_RAW, DP_RX_DECAP_TYPE_NATIVE_WIFI, -@@ -56,6 +84,9 @@ void ath11k_peer_rx_tid_delete(struct at +@@ -75,6 +103,9 @@ void ath11k_peer_rx_tid_delete(struct at int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id, u8 tid, u32 ba_win_sz, u16 ssn, enum hal_pn_type pn_type); @@ -3010,7 +3014,16 @@ Signed-off-by: Sriram R /* TODO: Do we need to enable ANI? */ --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -913,6 +913,7 @@ struct ath11k_base { +@@ -849,6 +849,8 @@ struct ath11k_soc_dp_tx_err_stats { + * idr unavailable etc. + */ + atomic_t misc_fail; ++ /* Tx failures due to NSS Tx error status */ ++ atomic_t nss_tx_fail; + }; + + struct ath11k_soc_dp_stats { +@@ -935,6 +937,7 @@ struct ath11k_base { struct list_head peers; wait_queue_head_t peer_mapping_wq; u8 mac_addr[ETH_ALEN]; diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch similarity index 82% rename from package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch rename to package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch index 34b30984ca..e30b5d761d 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-003-ath11k-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/199-003-ath11k-add-nss-support.patch @@ -156,15 +156,15 @@ Signed-off-by: Sriram R } --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -29,6 +29,7 @@ - #include "dbring.h" +@@ -30,6 +30,7 @@ #include "spectral.h" #include "wow.h" + #include "rx_desc.h" +#include "nss.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -381,6 +382,9 @@ struct ath11k_vif { +@@ -384,6 +385,9 @@ struct ath11k_vif { #endif /* CPTCFG_ATH11K_DEBUGFS */ struct ath11k_mgmt_frame_stats mgmt_stats; @@ -174,7 +174,7 @@ Signed-off-by: Sriram R }; struct ath11k_vif_iter { -@@ -520,6 +524,9 @@ struct ath11k_sta { +@@ -537,6 +541,9 @@ struct ath11k_sta { #endif bool use_4addr_set; @@ -184,7 +184,7 @@ Signed-off-by: Sriram R u16 tcl_metadata; /* Protected with ar->data_lock */ -@@ -610,6 +617,9 @@ struct ath11k { +@@ -632,6 +639,9 @@ struct ath11k { struct ieee80211_hw *hw; struct ieee80211_ops *ops; struct ath11k_pdev_wmi *wmi; @@ -194,15 +194,7 @@ Signed-off-by: Sriram R struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; struct ath11k_he ar_he; -@@ -827,6 +837,7 @@ struct ath11k_soc_dp_tx_err_stats { - * idr unavailable etc. - */ - atomic_t misc_fail; -+ atomic_t nss_tx_fail; - }; - - struct ath11k_soc_dp_stats { -@@ -868,9 +879,11 @@ struct ath11k_base { +@@ -892,9 +902,11 @@ struct ath11k_base { struct ath11k_htc htc; struct ath11k_dp dp; @@ -365,7 +357,7 @@ Signed-off-by: Sriram R if (ar->ab->hw_params.rxdma1_enable) { rx_ring = &dp->rxdma_mon_buf_ring; -@@ -1893,7 +1896,7 @@ static void ath11k_dp_rx_h_csum_offload( +@@ -2035,7 +2038,7 @@ static void ath11k_dp_rx_h_csum_offload( CHECKSUM_NONE : CHECKSUM_UNNECESSARY; } @@ -374,7 +366,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -1920,7 +1923,7 @@ static int ath11k_dp_rx_crypto_mic_len(s +@@ -2062,7 +2065,7 @@ static int ath11k_dp_rx_crypto_mic_len(s return 0; } @@ -383,7 +375,7 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -1948,7 +1951,7 @@ static int ath11k_dp_rx_crypto_param_len +@@ -2090,7 +2093,7 @@ static int ath11k_dp_rx_crypto_param_len return 0; } @@ -392,7 +384,56 @@ Signed-off-by: Sriram R enum hal_encrypt_type enctype) { switch (enctype) { -@@ -5239,7 +5242,7 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -2826,6 +2829,22 @@ static void ath11k_dp_rx_process_receive + } + } + ++void ath11k_dp_rx_from_nss(struct ath11k *ar, struct sk_buff *msdu, ++ struct napi_struct *napi) ++{ ++ struct ieee80211_rx_status rx_status = {0}; ++ struct ath11k_skb_rxcb *rxcb; ++ ++ rxcb = ATH11K_SKB_RXCB(msdu); ++ ++ ath11k_dp_rx_h_ppdu(ar, rxcb->rx_desc, &rx_status); ++ ath11k_dp_rx_h_mpdu(ar, msdu, rxcb->rx_desc, &rx_status); ++ ++ rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; ++ ++ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); ++} ++ + int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, + struct napi_struct *napi, int budget) + { +@@ -3133,6 +3152,13 @@ static void ath11k_dp_rx_update_user_sta + arsta = (struct ath11k_sta *)peer->sta->drv_priv; + rx_stats = arsta->rx_stats; + ++ if (ar->ab->nss.enabled) ++ ath11k_nss_update_sta_rxrate(ppdu_info, peer, user_stats); ++ ++ /* we've updated rate stats dont update dp rx stats if not enabled */ ++ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ return; ++ + if (!rx_stats) + return; + +@@ -3209,8 +3235,10 @@ static void ath11k_dp_rx_update_peer_mu_ + { + u32 num_users, i; + +- if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar)) ++ if (!ar->ab->nss.enabled && ++ !ath11k_debugfs_is_extd_rx_stats_enabled(ar)) { + return; ++ } + + num_users = ppdu_info->num_users; + if (num_users > HAL_MAX_UL_MU_USERS) +@@ -5613,7 +5641,7 @@ int ath11k_dp_rx_process_mon_status(stru struct sk_buff *skb; struct sk_buff_head skb_list; struct ath11k_peer *peer; @@ -401,9 +442,17 @@ Signed-off-by: Sriram R int num_buffs_reaped = 0; u32 rx_buf_sz; u16 log_type; +@@ -5681,6 +5709,7 @@ int ath11k_dp_rx_process_mon_status(stru + if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) { + arsta = (struct ath11k_sta *)peer->sta->drv_priv; + ath11k_dp_rx_update_peer_su_stats(arsta, ppdu_info); ++ ath11k_nss_update_sta_rxrate(ppdu_info, peer, NULL); + } else { + ath11k_dp_rx_mon_process_ulofdma(ppdu_info); + ath11k_dp_rx_update_peer_mu_stats(ar, ppdu_info); --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h -@@ -126,4 +126,16 @@ int ath11k_peer_rx_frag_setup(struct ath +@@ -145,4 +145,18 @@ int ath11k_peer_rx_frag_setup(struct ath int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab); int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer); @@ -419,6 +468,8 @@ Signed-off-by: Sriram R + struct hal_rx_desc *desc); +u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, + struct hal_rx_desc *desc); ++void ath11k_dp_rx_from_nss(struct ath11k *ar, struct sk_buff *msdu, ++ struct napi_struct *napi); #endif /* ATH11K_DP_RX_H */ --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -431,6 +482,21 @@ Signed-off-by: Sriram R enum hal_ring_type { HAL_REO_DST, HAL_REO_EXCEPTION, +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -938,6 +938,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + ppdu_info->num_mpdu_fcs_err = + FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR, + info0); ++ ++ if (ppdu_info->fc_valid) ++ ppdu_info->frame_control = ++ FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_FRAME_CTRL, ++ __le32_to_cpu(eu_stats->info2)); ++ + switch (ppdu_info->preamble_type) { + case HAL_RX_PREAMBLE_11N: + ppdu_info->ht_flags = 1; --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -24,6 +24,7 @@ @@ -573,7 +639,7 @@ Signed-off-by: Sriram R } } -@@ -6241,6 +6310,8 @@ static int ath11k_mac_config_mon_status_ +@@ -6241,6 +6308,8 @@ static int ath11k_mac_config_mon_status_ if (enable) { tlv_filter = ath11k_mac_mon_status_filter_default; @@ -582,7 +648,7 @@ Signed-off-by: Sriram R if (ath11k_debugfs_rx_filter(ar)) tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } -@@ -6539,7 +6610,7 @@ static int ath11k_mac_setup_vdev_create_ +@@ -6539,7 +6608,7 @@ static int ath11k_mac_setup_vdev_create_ return 0; } @@ -591,7 +657,7 @@ Signed-off-by: Sriram R struct ieee80211_vif *vif) { struct ath11k *ar = hw->priv; -@@ -6585,6 +6656,8 @@ static void ath11k_mac_op_update_vif_off +@@ -6585,6 +6654,8 @@ static void ath11k_mac_op_update_vif_off arvif->vdev_id, ret); vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED; } @@ -600,7 +666,7 @@ Signed-off-by: Sriram R } static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) -@@ -6715,6 +6788,8 @@ static int ath11k_mac_vdev_delete(struct +@@ -6715,6 +6786,8 @@ static int ath11k_mac_vdev_delete(struct reinit_completion(&ar->vdev_delete_done); @@ -609,7 +675,7 @@ Signed-off-by: Sriram R ret = ath11k_wmi_vdev_delete(ar, arvif->vdev_id); if (ret) { ath11k_warn(ar->ab, "failed to delete WMI vdev %d: %d\n", -@@ -6855,7 +6930,34 @@ static int ath11k_mac_op_add_interface(s +@@ -6855,7 +6928,34 @@ static int ath11k_mac_op_add_interface(s list_add(&arvif->list, &ar->arvifs); spin_unlock_bh(&ar->data_lock); @@ -645,7 +711,7 @@ Signed-off-by: Sriram R nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1; ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, -@@ -6979,6 +7081,7 @@ err_peer_del: +@@ -6979,6 +7079,7 @@ err_peer_del: } err_vdev_del: @@ -653,7 +719,7 @@ Signed-off-by: Sriram R ath11k_mac_vdev_delete(ar, arvif); spin_lock_bh(&ar->data_lock); list_del(&arvif->list); -@@ -7489,6 +7592,10 @@ ath11k_mac_update_vif_chan(struct ath11k +@@ -7489,6 +7590,10 @@ ath11k_mac_update_vif_chan(struct ath11k arvif->vdev_id, ret); continue; } @@ -664,7 +730,7 @@ Signed-off-by: Sriram R } /* Restart the internal monitor vdev on new channel */ -@@ -8717,6 +8824,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8717,6 +8822,8 @@ static void ath11k_mac_op_sta_statistics sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi) + ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -673,7 +739,7 @@ Signed-off-by: Sriram R } #if IS_ENABLED(CONFIG_IPV6) -@@ -9136,6 +9245,7 @@ static const struct ieee80211_ops ath11k +@@ -9144,6 +9251,7 @@ static const struct ieee80211_ops ath11k .update_vif_offload = ath11k_mac_op_update_vif_offload, .config = ath11k_mac_op_config, .bss_info_changed = ath11k_mac_op_bss_info_changed, @@ -681,7 +747,7 @@ Signed-off-by: Sriram R .configure_filter = ath11k_mac_op_configure_filter, .hw_scan = ath11k_mac_op_hw_scan, .cancel_hw_scan = ath11k_mac_op_cancel_hw_scan, -@@ -9521,7 +9631,8 @@ static int __ath11k_mac_register(struct +@@ -9530,7 +9638,8 @@ static int __ath11k_mac_register(struct ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW); ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER); ieee80211_hw_set(ar->hw, SUPPORTS_AMSDU_IN_AMPDU); @@ -691,7 +757,7 @@ Signed-off-by: Sriram R } ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; -@@ -9636,6 +9747,9 @@ static int __ath11k_mac_register(struct +@@ -9645,6 +9754,9 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; @@ -711,7 +777,7 @@ Signed-off-by: Sriram R static struct ath11k_peer *ath11k_peer_find_list_by_id(struct ath11k_base *ab, int peer_id) -@@ -136,6 +137,8 @@ void ath11k_peer_map_event(struct ath11k +@@ -150,6 +151,8 @@ void ath11k_peer_map_event(struct ath11k ether_addr_copy(peer->addr, mac_addr); list_add(&peer->list, &ab->peers); wake_up(&ab->peer_mapping_wq); @@ -720,7 +786,7 @@ Signed-off-by: Sriram R } ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "peer map vdev %d peer %pM id %d\n", -@@ -298,17 +301,13 @@ static int __ath11k_peer_delete(struct a +@@ -312,17 +315,13 @@ static int __ath11k_peer_delete(struct a lockdep_assert_held(&ar->conf_mutex); @@ -741,7 +807,7 @@ Signed-off-by: Sriram R /* Fallback to peer list search if the correct peer can't be found. * Skip the deletion of the peer from the rhash since it has already -@@ -327,10 +326,17 @@ static int __ath11k_peer_delete(struct a +@@ -341,10 +340,17 @@ static int __ath11k_peer_delete(struct a return -EINVAL; } @@ -760,17 +826,9 @@ Signed-off-by: Sriram R ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); if (ret) { -@@ -446,6 +452,7 @@ int ath11k_peer_create(struct ath11k *ar - peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; - peer->vif = arvif->vif; - -+ - if (sta) { - arsta = ath11k_sta_to_arsta(sta); - arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) | --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -17,6 +17,7 @@ struct ath11k_peer { +@@ -28,6 +28,7 @@ struct ath11k_peer { u16 ast_hash; u8 pdev_idx; u16 hw_peer_id; @@ -801,9 +859,9 @@ Signed-off-by: Sriram R #include "hif.h" +#include "qmi.h" - static const char *htt_bp_umac_ring[HTT_SW_UMAC_RING_IDX_MAX] = { - "REO2SW1_RING", -@@ -663,6 +662,7 @@ static ssize_t ath11k_write_extd_rx_stat + struct dentry *debugfs_ath11k; + +@@ -665,6 +664,7 @@ static ssize_t ath11k_write_extd_rx_stat HTT_RX_FP_DATA_FILTER_FLASG3; } else { tlv_filter = ath11k_mac_mon_status_filter_default; @@ -811,90 +869,18 @@ Signed-off-by: Sriram R } ar->debug.rx_filter = tlv_filter.rx_filter; -@@ -1669,72 +1669,6 @@ static const struct file_operations fops - .open = simple_open - }; - --int ath11k_debugfs_register(struct ath11k *ar) --{ -- struct ath11k_base *ab = ar->ab; -- char pdev_name[10]; -- char buf[100] = {0}; -- -- snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx); -- -- ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); -- if (IS_ERR(ar->debug.debugfs_pdev)) -- return PTR_ERR(ar->debug.debugfs_pdev); -- -- /* Create a symlink under ieee80211/phy* */ -- snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev); -- debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf); -- -- ath11k_debugfs_htt_stats_init(ar); -- -- ath11k_debugfs_fw_stats_init(ar); -- -- debugfs_create_file("ext_tx_stats", 0644, -- ar->debug.debugfs_pdev, ar, -- &fops_extd_tx_stats); -- debugfs_create_file("ext_rx_stats", 0644, -- ar->debug.debugfs_pdev, ar, -- &fops_extd_rx_stats); -- debugfs_create_file("pktlog_filter", 0644, -- ar->debug.debugfs_pdev, ar, -- &fops_pktlog_filter); -- debugfs_create_file("fw_dbglog_config", 0600, -- ar->debug.debugfs_pdev, ar, -- &fops_fw_dbglog); -- debugfs_create_file("dump_mgmt_stats", 0644, -- ar->debug.debugfs_pdev, ar, -- &fops_dump_mgmt_stats); -- -- if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) { -- debugfs_create_file("dfs_simulate_radar", 0200, -- ar->debug.debugfs_pdev, ar, -- &fops_simulate_radar); -- debugfs_create_bool("dfs_block_radar_events", 0200, -- ar->debug.debugfs_pdev, -- &ar->dfs_block_radar_events); -- } -- -- if (ab->hw_params.dbr_debug_support) -- debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev, -- ar, &fops_dbr_debug); -- -- debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar, -- &fops_ps_state_enable); -- -- if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT, -- ar->ab->wmi_ab.svc_map)) { -- debugfs_create_file("ps_timekeeper_enable", 0600, -- ar->debug.debugfs_pdev, ar, -- &fops_ps_timekeeper_enable); -- -- debugfs_create_file("reset_ps_duration", 0200, -- ar->debug.debugfs_pdev, ar, -- &fops_reset_ps_duration); -- } -- -- return 0; --} -- - void ath11k_debugfs_unregister(struct ath11k *ar) - { - struct ath11k_debug_dbr *dbr_debug; -@@ -1977,6 +1911,144 @@ static const struct file_operations ath1 +@@ -1687,6 +1687,76 @@ static const struct file_operations fops .open = simple_open }; ++ +static ssize_t ath11k_write_nss_stats(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct ath11k *ar = file->private_data; + struct ath11k_base *ab = ar->ab; -+ u32 nss_stats; ++ u8 nss_stats; + int ret; + + if (!ab->nss.enabled) { @@ -902,7 +888,7 @@ Signed-off-by: Sriram R + return -EINVAL; + } + -+ if (kstrtouint_from_user(ubuf, count, 0, &nss_stats)) ++ if (kstrtou8_from_user(ubuf, count, 0, &nss_stats)) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); @@ -957,78 +943,21 @@ Signed-off-by: Sriram R + .llseek = default_llseek, +}; + -+int ath11k_debugfs_register(struct ath11k *ar) -+{ -+ struct ath11k_base *ab = ar->ab; -+ char pdev_name[10]; -+ char buf[100] = {0}; -+ -+ snprintf(pdev_name, sizeof(pdev_name), "%s%u", "mac", ar->pdev_idx); -+ -+ ar->debug.debugfs_pdev = debugfs_create_dir(pdev_name, ab->debugfs_soc); -+ if (IS_ERR(ar->debug.debugfs_pdev)) -+ return PTR_ERR(ar->debug.debugfs_pdev); -+ -+ /* Create a symlink under ieee80211/phy* */ -+ snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev); -+ debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf); -+ -+ ath11k_debugfs_htt_stats_init(ar); -+ -+ ath11k_debugfs_fw_stats_init(ar); -+ -+ debugfs_create_file("ext_tx_stats", 0644, -+ ar->debug.debugfs_pdev, ar, -+ &fops_extd_tx_stats); -+ debugfs_create_file("ext_rx_stats", 0644, -+ ar->debug.debugfs_pdev, ar, -+ &fops_extd_rx_stats); -+ debugfs_create_file("pktlog_filter", 0644, -+ ar->debug.debugfs_pdev, ar, -+ &fops_pktlog_filter); -+ debugfs_create_file("fw_dbglog_config", 0600, -+ ar->debug.debugfs_pdev, ar, -+ &fops_fw_dbglog); -+ debugfs_create_file("dump_mgmt_stats", 0644, -+ ar->debug.debugfs_pdev, ar, -+ &fops_dump_mgmt_stats); -+ -+ if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) { -+ debugfs_create_file("dfs_simulate_radar", 0200, -+ ar->debug.debugfs_pdev, ar, -+ &fops_simulate_radar); -+ debugfs_create_bool("dfs_block_radar_events", 0200, -+ ar->debug.debugfs_pdev, -+ &ar->dfs_block_radar_events); -+ } -+ -+ if (ab->hw_params.dbr_debug_support) -+ debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev, -+ ar, &fops_dbr_debug); -+ -+ debugfs_create_file("ps_state_enable", 0600, ar->debug.debugfs_pdev, ar, -+ &fops_ps_state_enable); -+ -+ if (test_bit(WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT, -+ ar->ab->wmi_ab.svc_map)) { -+ debugfs_create_file("ps_timekeeper_enable", 0600, -+ ar->debug.debugfs_pdev, ar, -+ &fops_ps_timekeeper_enable); -+ -+ debugfs_create_file("reset_ps_duration", 0200, -+ ar->debug.debugfs_pdev, ar, -+ &fops_reset_ps_duration); -+ } -+ + int ath11k_debugfs_register(struct ath11k *ar) + { + struct ath11k_base *ab = ar->ab; +@@ -1753,6 +1823,11 @@ int ath11k_debugfs_register(struct ath11 + &fops_reset_ps_duration); + } + + if (ab->nss.enabled) + debugfs_create_file("nss_peer_stats_config", 0644, -+ ar->debug.debugfs_pdev, ar, &fops_nss_stats); ++ ar->debug.debugfs_pdev, ar, ++ &fops_nss_stats); + -+ return 0; -+} - void ath11k_debugfs_add_interface(struct ath11k_vif *arvif) - { - struct ath11k_base *ab = arvif->ar->ab; + return 0; + } + --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -12,7 +12,7 @@ @@ -1062,7 +991,7 @@ Signed-off-by: Sriram R #include "hif.h" #include "wmi.h" #include "../../../../../net/mac80211/sta_info.h" -@@ -465,7 +467,7 @@ deliver_amsdu: +@@ -466,7 +468,7 @@ deliver_amsdu: /* create list containing all the subframes */ ieee80211_amsdu_to_8023s(skb, &subframe_list, NULL, @@ -1071,7 +1000,7 @@ Signed-off-by: Sriram R /* This shouldn't happen, indicating error during defragmentation */ if (skb_queue_empty(&subframe_list)) -@@ -657,12 +659,14 @@ drop: +@@ -658,12 +660,14 @@ drop: return -EINVAL; } @@ -1087,7 +1016,7 @@ Signed-off-by: Sriram R if (!ar->ab->nss.enabled) return 0; -@@ -675,6 +679,22 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -676,6 +680,22 @@ int ath11k_nss_vdev_set_cmd(struct ath11 if (!vdev_msg) return -ENOMEM; @@ -1110,7 +1039,7 @@ Signed-off-by: Sriram R /* TODO: Convert to function for conversion in case of many * such commands */ -@@ -1136,7 +1156,6 @@ void ath11k_nss_update_sta_stats(struct +@@ -1137,7 +1157,6 @@ void ath11k_nss_update_sta_stats(struct { struct sta_info *stainfo; struct ath11k_peer *peer; @@ -1118,7 +1047,7 @@ Signed-off-by: Sriram R struct ath11k *ar = arsta->arvif->ar; struct ath11k_base *ab = ar->ab; -@@ -1230,6 +1249,9 @@ void ath11k_nss_update_sta_rxrate(struct +@@ -1231,6 +1250,9 @@ void ath11k_nss_update_sta_rxrate(struct if (!ab->nss.enabled) return; @@ -1128,7 +1057,7 @@ Signed-off-by: Sriram R if (!peer->nss.nss_stats) return; -@@ -1289,7 +1311,7 @@ void ath11k_nss_update_sta_rxrate(struct +@@ -1290,7 +1312,7 @@ void ath11k_nss_update_sta_rxrate(struct peer->nss.nss_stats->rxrate.mcs = mcs; peer->nss.nss_stats->rxrate.flags = RATE_INFO_FLAGS_HE_MCS; peer->nss.nss_stats->rxrate.he_dcm = ppdu_info->dcm; diff --git a/package/kernel/mac80211/patches/nss/ath11k/203-mac80211-ath11k-fw-dynamic-muedca.patch b/package/kernel/mac80211/patches/nss/ath11k/203-mac80211-ath11k-fw-dynamic-muedca.patch new file mode 100644 index 0000000000..a91d4aa97c --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/203-mac80211-ath11k-fw-dynamic-muedca.patch @@ -0,0 +1,162 @@ +From ed838800bb8f4c59b320395066ac356f74528a50 Mon Sep 17 00:00:00 2001 +From: Muna Sinada +Date: Wed, 29 Jul 2020 00:11:30 -0700 +Subject: [PATCH] 203-mac80211-ath11k-fw-dynamic-muedca.patch + +mac80211/ath11k:FW Initiated Dynamic MU-EDCA + +Implementing the updating of firmware initiated dynamic MU-EDCA +parameters in Beacon IE. Firmware routinely checks its clients and +updates its MU-EDCA values every 3 seconds. Firmware is tuning +MU-EDCA parameters to improve performance. As part of this process, +the firmware informs host about new MU-EDCA values utilizing +WMI_MUEDCA_PARAMS_CONFIG_EVENTID. FW expectation is that host will +update MU-EDCA parameters in the Beacon IE. +Implementation consists of: + (1) Receiving updated parameters through event in ATH11k + (2) Passing updated parameters ATH11k -> mac80211 -> cfg80211 + (3) Passing updated parameters to user space. + +Signed-off-by: Muna Sinada +--- + drivers/net/wireless/ath/ath11k/wmi.c | 97 +++++++++++++++++++++++++++++++---- + drivers/net/wireless/ath/ath11k/wmi.h | 12 +++++ + include/net/cfg80211.h | 11 ++++ + include/net/mac80211.h | 13 +++++ + include/uapi/linux/nl80211.h | 10 ++++ + net/mac80211/mlme.c | 12 +++++ + net/mac80211/trace.h | 20 ++++++++ + net/wireless/nl80211.c | 36 +++++++++++++ + 8 files changed, 200 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -148,6 +148,8 @@ static const struct wmi_tlv_policy wmi_t + .min_len = sizeof(struct wmi_vdev_delete_resp_event) }, + [WMI_TAG_OBSS_COLOR_COLLISION_EVT] = { + .min_len = sizeof(struct wmi_obss_color_collision_event) }, ++ [WMI_TAG_MUEDCA_PARAMS_CONFIG_EVENT] = { ++ .min_len = sizeof(struct wmi_pdev_update_muedca_event) }, + [WMI_TAG_11D_NEW_COUNTRY_EVENT] = { + .min_len = sizeof(struct wmi_11d_new_cc_ev) }, + [WMI_TAG_PER_CHAIN_RSSI_STATS] = { +@@ -8727,6 +8729,74 @@ exit: + kfree(tb); + } + ++static void ++ath11k_wmi_pdev_update_muedca_params_status_event(struct ath11k_base *ab, ++ struct sk_buff *skb) ++{ ++ const void **tb; ++ const struct wmi_pdev_update_muedca_event *ev; ++ struct ieee80211_mu_edca_param_set *params; ++ struct ath11k *ar; ++ int ret; ++ ++ tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); ++ if (IS_ERR(tb)) { ++ ret = PTR_ERR(tb); ++ ath11k_warn(ab, "failed to parse tlv: %d\n", ret); ++ return; ++ } ++ ++ ev = tb[WMI_TAG_MUEDCA_PARAMS_CONFIG_EVENT]; ++ if (!ev) { ++ ath11k_warn(ab, "failed to fetch pdev update muedca params ev"); ++ goto exit; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_WMI, ++ "Update MU-EDCA parameters for pdev:%d\n", ev->pdev_id); ++ ++ ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id); ++ if (!ar) { ++ ath11k_warn(ab, ++ "MU-EDCA parameter change in invalid pdev %d\n", ++ ev->pdev_id); ++ goto exit; ++ } ++ ++ params = kzalloc(sizeof(*params), GFP_ATOMIC); ++ if (!params) { ++ ath11k_warn(ab, ++ "Failed to allocate memory for updated MU-EDCA Parameters"); ++ goto exit; ++ } ++ ++ params->ac_be.aifsn = ev->aifsn[0]; ++ params->ac_be.ecw_min_max = ((0xF & ev->ecwmax[0]) << 4) | ++ (0xF & ev->ecwmin[0]); ++ params->ac_be.mu_edca_timer = ev->muedca_expiration_time[0]; ++ ++ params->ac_bk.aifsn = ev->aifsn[1]; ++ params->ac_bk.ecw_min_max = ((0xF & ev->ecwmax[1]) << 4) | ++ (0xF & ev->ecwmin[1]); ++ params->ac_bk.mu_edca_timer = ev->muedca_expiration_time[1]; ++ ++ params->ac_vi.aifsn = ev->aifsn[2]; ++ params->ac_vi.ecw_min_max = ((0xF & ev->ecwmax[2]) << 4) | ++ (0xF & ev->ecwmin[2]); ++ params->ac_vi.mu_edca_timer = ev->muedca_expiration_time[2]; ++ ++ params->ac_vo.aifsn = ev->aifsn[3]; ++ params->ac_vo.ecw_min_max = ((0xF & ev->ecwmax[3]) << 4) | ++ (0xF & ev->ecwmin[3]); ++ params->ac_vo.mu_edca_timer = ev->muedca_expiration_time[3]; ++ ++ ieee80211_update_muedca_params(ar->hw, params, GFP_ATOMIC); ++ ++ kfree(params); ++exit: ++ kfree(tb); ++} ++ + static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) + { + struct wmi_cmd_hdr *cmd_hdr; +@@ -8845,6 +8915,9 @@ static void ath11k_wmi_tlv_op_rx(struct + case WMI_11D_NEW_COUNTRY_EVENTID: + ath11k_reg_11d_new_cc_event(ab, skb); + break; ++ case WMI_MUEDCA_PARAMS_CONFIG_EVENTID: ++ ath11k_wmi_pdev_update_muedca_params_status_event(ab, skb); ++ break; + case WMI_DIAG_EVENTID: + ath11k_wmi_diag_event(ab, skb); + break; +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -759,6 +759,7 @@ enum wmi_tlv_event_id { + WMI_READ_DATA_FROM_FLASH_EVENTID, + WMI_REPORT_RX_AGGR_FAILURE_EVENTID, + WMI_PKGID_EVENTID, ++ WMI_MUEDCA_PARAMS_CONFIG_EVENTID = 0x1d01e, + WMI_GPIO_INPUT_EVENTID = WMI_TLV_CMD(WMI_GRP_GPIO), + WMI_UPLOADH_EVENTID, + WMI_CAPTUREH_EVENTID, +@@ -1869,6 +1870,7 @@ enum wmi_tlv_tag { + WMI_TAG_NDP_EVENT, + WMI_TAG_PDEV_PEER_PKTLOG_FILTER_CMD = 0x301, + WMI_TAG_PDEV_PEER_PKTLOG_FILTER_INFO, ++ WMI_TAG_MUEDCA_PARAMS_CONFIG_EVENT = 0x32a, + WMI_TAG_FILS_DISCOVERY_TMPL_CMD = 0x344, + WMI_TAG_PDEV_SRG_BSS_COLOR_BITMAP_CMD = 0x37b, + WMI_TAG_PDEV_SRG_PARTIAL_BSSID_BITMAP_CMD, +@@ -4868,6 +4870,16 @@ struct wmi_pdev_temperature_event { + u32 pdev_id; + } __packed; + ++#define WMI_AC_MAX 4 ++ ++struct wmi_pdev_update_muedca_event { ++ u32 pdev_id; ++ u32 aifsn[WMI_AC_MAX]; ++ u32 ecwmin[WMI_AC_MAX]; ++ u32 ecwmax[WMI_AC_MAX]; ++ u32 muedca_expiration_time[WMI_AC_MAX]; ++} __packed; ++ + #define WMI_RX_STATUS_OK 0x00 + #define WMI_RX_STATUS_ERR_CRC 0x01 + #define WMI_RX_STATUS_ERR_DECRYPT 0x08 diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch similarity index 99% rename from package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch rename to package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch index a937ffba79..a765d1a292 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -21,7 +21,7 @@ Signed-off-by: Seevalamuthu Mariappan --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -116,6 +116,7 @@ struct ath11k_skb_cb { +@@ -119,6 +119,7 @@ struct ath11k_skb_cb { u32 cipher; struct ath11k *ar; struct ieee80211_vif *vif; @@ -369,7 +369,7 @@ Signed-off-by: Seevalamuthu Mariappan int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9764,6 +9764,9 @@ static int __ath11k_mac_register(struct +@@ -9771,6 +9771,9 @@ static int __ath11k_mac_register(struct */ ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch similarity index 68% rename from package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch rename to package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch index 4d7af86413..4d9c1537a8 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-ath11k-Enable-256_512MB-profiles.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/207-ath11k-Enable-256_512MB-profiles.patch @@ -45,34 +45,21 @@ Signed-off-by: Ramya Gnanasekar depends on m --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -11,11 +11,43 @@ +@@ -11,11 +11,29 @@ #include "wmi.h" /* Target configuration defines */ -+#if defined(CPTCFG_ATH11K_MEM_PROFILE_256M) -+#define TARGET_NUM_VDEVS(ab) 8 -+#define TARGET_NUM_PEERS_PDEV(ab) (128 + TARGET_NUM_VDEVS(ab)) -+/* Max num of stations (per radio) */ -+#define TARGET_NUM_STATIONS(ab) 128 -+#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_256M -+#define ATH11K_DP_TX_COMP_RING_SIZE 2048 -+#define ATH11K_DP_RXDMA_BUF_RING_SIZE 1024 -+#define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE 512 -+#define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 128 -+#define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 128 -+ -+#elif defined(CPTCFG_ATH11K_MEM_PROFILE_512M) ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + +#define TARGET_NUM_VDEVS(ab) 8 +#define TARGET_NUM_PEERS_PDEV(ab) (128 + TARGET_NUM_VDEVS(ab)) +/* Max num of stations (per radio) */ +#define TARGET_NUM_STATIONS(ab) 128 +#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_512M +#define ATH11K_DP_TX_COMP_RING_SIZE 8192 -+#define ATH11K_DP_RXDMA_BUF_RING_SIZE 4096 +#define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE 512 +#define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 128 +#define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 128 - +#else /* Num VDEVS per radio */ -#define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs) @@ -84,7 +71,6 @@ Signed-off-by: Ramya Gnanasekar +#define TARGET_NUM_STATIONS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_peers) +#define ATH11K_QMI_TARGET_MEM_MODE ATH11K_QMI_TARGET_MEM_MODE_DEFAULT +#define ATH11K_DP_TX_COMP_RING_SIZE 32768 -+#define ATH11K_DP_RXDMA_BUF_RING_SIZE 4096 +#define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE 1024 +#define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 +#define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 2048 @@ -92,7 +78,7 @@ Signed-off-by: Ramya Gnanasekar /* Num of peers for Single Radio mode */ #define TARGET_NUM_PEERS_SINGLE(ab) (TARGET_NUM_PEERS_PDEV(ab)) -@@ -26,9 +58,6 @@ +@@ -26,9 +44,6 @@ /* Num of peers for DBS_SBS */ #define TARGET_NUM_PEERS_DBS_SBS(ab) (3 * TARGET_NUM_PEERS_PDEV(ab)) @@ -102,7 +88,7 @@ Signed-off-by: Ramya Gnanasekar #define TARGET_NUM_PEERS(ab, x) TARGET_NUM_PEERS_##x(ab) #define TARGET_NUM_PEER_KEYS 2 #define TARGET_NUM_TIDS(ab, x) (2 * TARGET_NUM_PEERS(ab, x) + \ -@@ -226,6 +255,7 @@ struct ath11k_hw_params { +@@ -226,6 +241,7 @@ struct ath11k_hw_params { u32 tx_ring_size; bool smp2p_wow_exit; bool support_fw_mac_sequence; @@ -125,17 +111,18 @@ Signed-off-by: Ramya Gnanasekar #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 #define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x003E -@@ -519,4 +525,10 @@ int ath11k_qmi_init_service(struct ath11 - void ath11k_qmi_free_resource(struct ath11k_base *ab); - int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab); +@@ -42,6 +48,11 @@ + #define ATH11K_QMI_DEVICE_BAR_SIZE 0x200000 + struct ath11k_base; +enum ath11k_target_mem_mode { -+ ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, -+ ATH11K_QMI_TARGET_MEM_MODE_512M, -+ ATH11K_QMI_TARGET_MEM_MODE_256M, ++ ATH11K_QMI_TARGET_MEM_MODE_DEFAULT = 0, ++ ATH11K_QMI_TARGET_MEM_MODE_512M, ++ ATH11K_QMI_TARGET_MEM_MODE_256M, +}; -+ - #endif + + enum ath11k_qmi_file_type { + ATH11K_QMI_FILE_TYPE_BDF_GOLDEN, --- a/local-symbols +++ b/local-symbols @@ -171,6 +171,8 @@ ATH11K= @@ -149,28 +136,27 @@ Signed-off-by: Ramya Gnanasekar ATH11K_TRACING= --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -863,6 +863,11 @@ struct ath11k_msi_config { +@@ -887,6 +887,11 @@ struct ath11k_msi_config { u16 hw_rev; }; +struct ath11k_num_vdevs_peers { -+ u32 num_vdevs; -+ u32 num_peers; ++ u32 num_vdevs; ++ u32 num_peers; +}; + /* Master structure to hold the hw data which may be used in core module */ struct ath11k_base { enum ath11k_hw_rev hw_rev; -@@ -1016,6 +1021,9 @@ struct ath11k_base { - } testmode; - #endif +@@ -1032,6 +1037,8 @@ struct ath11k_base { + const struct ath11k_pci_ops *ops; + } pci; + atomic_t num_max_allowed; -+ struct ath11k_num_vdevs_peers *num_vdevs_peers; + - /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); - }; + #ifdef CPTCFG_NL80211_TESTMODE + struct { + u32 data_pos; --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -206,8 +206,9 @@ struct ath11k_pdev_dp { @@ -180,7 +166,7 @@ Signed-off-by: Ramya Gnanasekar -#define DP_TX_COMP_RING_SIZE 32768 +#define DP_TX_COMP_RING_SIZE ATH11K_DP_TX_COMP_RING_SIZE #define DP_TX_IDR_SIZE DP_TX_COMP_RING_SIZE -+#define DP_TX_COMP_MAX_ALLOWED DP_TX_COMP_RING_SIZE ++#define DP_TX_COMP_MAX_ALLOWED DP_TX_COMP_RING_SIZE #define DP_TCL_CMD_RING_SIZE 32 #define DP_TCL_STATUS_RING_SIZE 32 #define DP_REO_DST_RING_MAX 4 @@ -199,7 +185,7 @@ Signed-off-by: Ramya Gnanasekar #define DP_RX_RELEASE_RING_NUM 3 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -265,6 +265,7 @@ tcl_ring_sel: +@@ -334,6 +334,7 @@ tcl_ring_sel: skb->data, skb->len); atomic_inc(&ar->dp.num_tx_pending); @@ -207,7 +193,7 @@ Signed-off-by: Ramya Gnanasekar return 0; -@@ -309,6 +310,7 @@ static void ath11k_dp_tx_free_txbuf(stru +@@ -380,6 +381,7 @@ static void ath11k_dp_tx_free_txbuf(stru ar = ab->pdevs[mac_id].ar; if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); @@ -215,7 +201,7 @@ Signed-off-by: Ramya Gnanasekar } static void -@@ -342,6 +344,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct +@@ -411,6 +413,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); @@ -223,7 +209,7 @@ Signed-off-by: Ramya Gnanasekar dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -@@ -769,6 +772,7 @@ void ath11k_dp_tx_completion_handler(str +@@ -825,6 +828,7 @@ void ath11k_dp_tx_completion_handler(str wake_up(&ar->dp.tx_empty_waitq); ath11k_dp_tx_complete_msdu(ar, msdu, &ts); @@ -233,23 +219,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - #include "core.h" - #include "dp_tx.h" -@@ -16,6 +17,7 @@ - #include "debug.h" - #include "hif.h" - #include "wow.h" -+#include "ahb.h" - - unsigned int nss_offload; - #ifdef CPTCFG_ATH11K_NSS_SUPPORT -@@ -42,6 +44,8 @@ bool ath11k_ftm_mode; +@@ -42,6 +42,8 @@ bool ath11k_ftm_mode; module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444); MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode"); @@ -258,44 +228,24 @@ Signed-off-by: Ramya Gnanasekar static struct ath11k_hw_params ath11k_hw_params[] = { { .hw_rev = ATH11K_HW_IPQ8074, -@@ -95,15 +99,15 @@ static struct ath11k_hw_params ath11k_hw - .coldboot_cal_mm = false, - .coldboot_cal_ftm = false, - .cbcal_restart_fw = true, -- .fw_mem_mode = 0, -+ .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, - .num_vdevs = 16 + 1, - .num_peers = 512, - .supports_suspend = false, - .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), -+ .reo_dest_ring_map_shift = HAL_REO_DEST_RING_CTRL_HASH_RING_SHIFT, - .supports_regdb = false, - .fix_l1ss = true, - .credit_flow = false, -- .max_tx_ring = DP_TCL_NUM_RING_MAX, - .hal_params = &ath11k_hw_hal_params_ipq8074, - .supports_dynamic_smps_6ghz = false, - .alloc_cacheable_memory = true, -@@ -127,6 +131,9 @@ static struct ath11k_hw_params ath11k_hw +@@ -127,6 +129,7 @@ static struct ath11k_hw_params ath11k_hw .tcl_ring_retry = true, .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, -+ /* In addition to TCL ring use TCL_CMD ring also for tx */ -+ .max_tx_ring = DP_TCL_NUM_RING_MAX + 1, + .num_vdevs_peers = ath11k_vdevs_peers, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, -@@ -177,7 +183,7 @@ static struct ath11k_hw_params ath11k_hw - .coldboot_cal_mm = true, - .coldboot_cal_ftm = true, +@@ -177,7 +180,7 @@ static struct ath11k_hw_params ath11k_hw + .coldboot_cal_mm = false, + .coldboot_cal_ftm = false, .cbcal_restart_fw = true, - .fw_mem_mode = 0, + .fw_mem_mode = ATH11K_QMI_TARGET_MEM_MODE, .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -259,7 +265,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -259,7 +262,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -304,7 +254,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -426,7 +432,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -426,7 +429,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -313,7 +263,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -509,7 +515,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -462,6 +465,7 @@ static struct ath11k_hw_params ath11k_hw + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, ++ .num_vdevs_peers = ath11k_vdevs_peers, + }, + { + .name = "wcn6855 hw2.1", +@@ -509,7 +513,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = false, .coldboot_cal_ftm = false, .cbcal_restart_fw = false, @@ -322,7 +280,15 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = true, -@@ -593,7 +599,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -545,6 +549,7 @@ static struct ath11k_hw_params ath11k_hw + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, ++ .num_vdevs_peers = ath11k_vdevs_peers, + }, + { + .name = "wcn6750 hw1.0", +@@ -593,7 +598,7 @@ static struct ath11k_hw_params ath11k_hw .coldboot_cal_mm = true, .coldboot_cal_ftm = true, .cbcal_restart_fw = false, @@ -331,7 +297,7 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_suspend = false, -@@ -672,7 +678,7 @@ static struct ath11k_hw_params ath11k_hw +@@ -672,7 +677,7 @@ static struct ath11k_hw_params ath11k_hw .supports_monitor = false, .supports_sta_ps = false, .supports_shadow_regs = false, @@ -340,11 +306,14 @@ Signed-off-by: Ramya Gnanasekar .num_vdevs = 16 + 1, .num_peers = 512, .supports_regdb = false, -@@ -710,7 +716,23 @@ static struct ath11k_hw_params ath11k_hw - }, - }; - --static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) +@@ -707,6 +712,22 @@ static struct ath11k_hw_params ath11k_hw + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = false, ++ .num_vdevs_peers = ath11k_vdevs_peers, ++ }, ++}; ++ +static const struct ath11k_num_vdevs_peers ath11k_vdevs_peers[] = { + { + .num_vdevs = (16 + 1), @@ -357,22 +326,6 @@ Signed-off-by: Ramya Gnanasekar + { + .num_vdevs = 8, + .num_peers = 128, -+ }, -+}; -+ -+static inline struct ath11k_pdev * -+ath11k_core_get_single_pdev(struct ath11k_base *ab) - { - WARN_ON(!ab->hw_params.single_pdev_only); + }, + }; ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1595,7 +1595,7 @@ static ssize_t ath11k_dump_mgmt_stats(st - struct ath11k_vif *arvif = NULL; - struct ath11k_mgmt_frame_stats *mgmt_stats; - int len = 0, ret, i; -- int size = (TARGET_NUM_VDEVS - 1) * 1500; -+ int size = (TARGET_NUM_VDEVS(ab) - 1) * 1500; - char *buf; - const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX-1] = {"assoc_req", "assoc_resp", - "reassoc_req", "reassoc_resp", diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch b/package/kernel/mac80211/patches/nss/ath11k/211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch similarity index 96% rename from package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch rename to package/kernel/mac80211/patches/nss/ath11k/211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch index 47146c459e..a470ba9345 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/211-001-ath11k-add-WDS-offload-changes-to-NSS-driver-interface.patch @@ -13,9 +13,9 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -348,6 +348,22 @@ void ath11k_nss_wifili_event_receive(str - ath11k_nss_wifili_link_desc_return(ab, - (void *)&msg->msg.linkdescinfomsg); +@@ -307,6 +307,22 @@ void ath11k_nss_wifili_event_receive(str + case NSS_WIFILI_TID_REOQ_SETUP_MSG: + /* TODO setup tidq */ break; + case NSS_WIFILI_WDS_PEER_ADD_MSG: + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer add event received %d response %d error %d\n", @@ -36,7 +36,7 @@ Signed-off-by: Sathishkumar Muruganandam default: ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); break; -@@ -458,13 +476,6 @@ static void ath11k_nss_vdev_event_receiv +@@ -417,13 +433,6 @@ static void ath11k_nss_vdev_event_receiv /*TODO*/ } @@ -50,7 +50,7 @@ Signed-off-by: Sathishkumar Muruganandam /* TODO: move to mac80211 after cleanups/refactoring required after feature completion */ static int ath11k_nss_deliver_rx(struct ieee80211_vif *vif, struct sk_buff *skb, bool eth, int data_offs, struct napi_struct *napi) -@@ -588,11 +599,239 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -547,11 +556,239 @@ static int ath11k_nss_undecap_nwifi(stru return 0; } @@ -291,7 +291,7 @@ Signed-off-by: Sathishkumar Muruganandam struct wireless_dev *wdev = NULL; struct ieee80211_vif *vif = NULL; struct ath11k_vif *arvif; -@@ -632,28 +871,16 @@ ath11k_nss_vdev_data_receive(struct net_ +@@ -591,28 +828,16 @@ ath11k_nss_vdev_data_receive(struct net_ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "dp rx msdu from nss: ", skb->data, skb->len); @@ -327,7 +327,7 @@ Signed-off-by: Sathishkumar Muruganandam dev_kfree_skb_any(skb); return; } -@@ -1362,7 +1589,7 @@ void ath11k_nss_update_sta_rxrate(struct +@@ -1321,7 +1546,7 @@ void ath11k_nss_update_sta_rxrate(struct peer->nss.nss_stats->rxrate.bw = ath11k_mac_bw_to_mac80211_bw(ppdu_info->bw); } @@ -336,7 +336,7 @@ Signed-off-by: Sathishkumar Muruganandam { struct nss_wifili_peer_msg *peer_msg; struct nss_wifili_msg *wlmsg = NULL; -@@ -1376,9 +1603,10 @@ int ath11k_nss_peer_delete(struct ath11k +@@ -1335,9 +1560,10 @@ int ath11k_nss_peer_delete(struct ath11k spin_lock_bh(&ab->base_lock); @@ -349,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam spin_unlock_bh(&ab->base_lock); return -EINVAL; } -@@ -1451,8 +1679,9 @@ free_peer: +@@ -1410,8 +1636,9 @@ free_peer: return ret; } @@ -360,7 +360,7 @@ Signed-off-by: Sathishkumar Muruganandam struct nss_wifili_peer_msg *peer_msg; struct nss_wifili_msg *wlmsg = NULL; nss_wifili_msg_callback_t msg_cb; -@@ -1509,17 +1738,23 @@ int ath11k_nss_peer_create(struct ath11k +@@ -1468,17 +1695,23 @@ int ath11k_nss_peer_create(struct ath11k status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); if (status != NSS_TX_SUCCESS) { ret = -EINVAL; @@ -387,7 +387,7 @@ Signed-off-by: Sathishkumar Muruganandam peer->nss.nss_stats = kzalloc(sizeof(*peer->nss.nss_stats), GFP_ATOMIC); if (!peer->nss.nss_stats) { ret = -ENOMEM; -@@ -1538,6 +1773,199 @@ msg_free: +@@ -1497,6 +1730,199 @@ msg_free: return ret; } @@ -587,7 +587,7 @@ Signed-off-by: Sathishkumar Muruganandam /*-------------------------------INIT/DEINIT---------------------------------*/ static int ath11k_nss_radio_buf_cfg(struct ath11k *ar, int range, int buf_sz) -@@ -1931,7 +2359,7 @@ static int ath11k_nss_init(struct ath11k +@@ -1890,7 +2316,7 @@ static int ath11k_nss_init(struct ath11k status = nss_wifili_tx_msg(nss_contex, wlmsg); if (status != NSS_TX_SUCCESS) { @@ -596,7 +596,7 @@ Signed-off-by: Sathishkumar Muruganandam goto unregister; } -@@ -1985,7 +2413,8 @@ static int ath11k_nss_stats_cfg(struct a +@@ -1944,7 +2370,8 @@ static int ath11k_nss_stats_cfg(struct a status = nss_wifili_tx_msg(ar->nss.ctx, wlmsg); if (status != NSS_TX_SUCCESS) { @@ -624,7 +624,7 @@ Signed-off-by: Sathishkumar Muruganandam /* WIFILI Supported Target Types */ #define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF -@@ -208,11 +210,19 @@ int ath11k_nss_vdev_create(struct ath11k +@@ -205,11 +207,19 @@ int ath11k_nss_vdev_create(struct ath11k void ath11k_nss_vdev_delete(struct ath11k_vif *arvif); int ath11k_nss_vdev_up(struct ath11k_vif *arvif); int ath11k_nss_vdev_down(struct ath11k_vif *arvif); @@ -646,7 +646,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_nss_set_peer_sec_type(struct ath11k *ar, struct ath11k_peer *peer, struct ieee80211_key_conf *key_conf); void ath11k_nss_update_sta_stats(struct station_info *sinfo, -@@ -274,12 +284,37 @@ static inline int ath11k_nss_vdev_down(s +@@ -271,12 +281,37 @@ static inline int ath11k_nss_vdev_down(s return 0; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch b/package/kernel/mac80211/patches/nss/ath11k/211-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch similarity index 93% rename from package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch rename to package/kernel/mac80211/patches/nss/ath11k/211-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch index 0e6c0d92d2..8ad2cc71f8 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/211-002-ath11k-add-WDS-offload-support-on-NSS-offload-for-STA-mode.patch @@ -26,7 +26,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -634,6 +634,7 @@ struct ath11k { +@@ -642,6 +642,7 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_nss nss; @@ -34,18 +34,19 @@ Signed-off-by: Sathishkumar Muruganandam #endif struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; -@@ -1042,6 +1043,8 @@ struct ath11k_base { - u32 rx_hash; - bool stats_disable; +@@ -1047,6 +1048,9 @@ struct ath11k_base { + } testmode; + #endif + u32 max_ast_index; + u32 num_ast_entries; ++ /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -1142,13 +1142,16 @@ struct htt_t2h_peer_map_event { +@@ -1105,13 +1105,16 @@ struct htt_t2h_peer_map_event { #define HTT_T2H_PEER_UNMAP_INFO_PEER_ID HTT_T2H_PEER_MAP_INFO_PEER_ID #define HTT_T2H_PEER_UNMAP_INFO1_MAC_ADDR_H16 \ HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16 @@ -66,7 +67,7 @@ Signed-off-by: Sathishkumar Muruganandam struct htt_resp_msg { --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1756,6 +1756,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -1857,6 +1857,8 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s u16 peer_mac_h16; u16 ast_hash; u16 hw_peer_id; @@ -75,7 +76,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type); -@@ -1791,15 +1793,29 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s +@@ -1892,15 +1894,29 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s resp->peer_map_ev.info2); hw_peer_id = FIELD_GET(HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID, resp->peer_map_ev.info1); @@ -110,7 +111,7 @@ Signed-off-by: Sathishkumar Muruganandam break; --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -431,7 +431,7 @@ ath11k_dp_tx_process_htt_tx_complete(str +@@ -495,7 +495,7 @@ ath11k_dp_tx_process_htt_tx_complete(str break; case HAL_WBM_REL_HTT_TX_COMP_STATUS_MEC_NOTIFY: /* This event is to be handled only when the driver decides to @@ -121,7 +122,7 @@ Signed-off-by: Sathishkumar Muruganandam default: --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -94,6 +94,287 @@ struct ath11k_peer *ath11k_peer_find_by_ +@@ -108,6 +108,287 @@ struct ath11k_peer *ath11k_peer_find_by_ return NULL; } @@ -409,7 +410,7 @@ Signed-off-by: Sathishkumar Muruganandam void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) { struct ath11k_peer *peer; -@@ -118,11 +399,67 @@ exit: +@@ -132,11 +413,67 @@ exit: spin_unlock_bh(&ab->base_lock); } @@ -477,7 +478,7 @@ Signed-off-by: Sathishkumar Muruganandam spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, vdev_id, mac_addr); if (!peer) { -@@ -137,8 +474,8 @@ void ath11k_peer_map_event(struct ath11k +@@ -151,8 +488,8 @@ void ath11k_peer_map_event(struct ath11k ether_addr_copy(peer->addr, mac_addr); list_add(&peer->list, &ab->peers); wake_up(&ab->peer_mapping_wq); @@ -488,7 +489,7 @@ Signed-off-by: Sathishkumar Muruganandam } ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "peer map vdev %d peer %pM id %d\n", -@@ -146,6 +483,69 @@ void ath11k_peer_map_event(struct ath11k +@@ -160,6 +497,69 @@ void ath11k_peer_map_event(struct ath11k exit: spin_unlock_bh(&ab->base_lock); @@ -558,7 +559,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_wait_for_peer_common(struct ath11k_base *ab, int vdev_id, -@@ -242,20 +642,34 @@ err_clean: +@@ -256,20 +656,34 @@ err_clean: void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) { @@ -595,7 +596,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_peer_rhash_delete(ab, peer); list_del(&peer->list); kfree(peer); -@@ -302,7 +716,7 @@ static int __ath11k_peer_delete(struct a +@@ -316,7 +730,7 @@ static int __ath11k_peer_delete(struct a lockdep_assert_held(&ar->conf_mutex); reinit_completion(&ar->peer_delete_done); @@ -604,7 +605,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_lock(&ab->tbl_mtx_lock); spin_lock_bh(&ab->base_lock); -@@ -377,6 +791,7 @@ int ath11k_peer_create(struct ath11k *ar +@@ -391,6 +805,7 @@ int ath11k_peer_create(struct ath11k *ar struct ieee80211_sta *sta, struct peer_create_params *param) { struct ath11k_peer *peer; @@ -612,27 +613,25 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_sta *arsta; int ret, fbret; -@@ -450,7 +865,14 @@ int ath11k_peer_create(struct ath11k *ar - - peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; +@@ -466,6 +881,13 @@ int ath11k_peer_create(struct ath11k *ar peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; -- peer->vif = arvif->vif; -+ peer->vif = vif; -+ + peer->vif = arvif->vif; + +#ifdef CPTCFG_ATH11K_NSS_SUPPORT + if (vif->type == NL80211_IFTYPE_STATION && ar->ab->nss.enabled) + ar->bss_peer = peer; + else + ar->bss_peer = NULL; +#endif - - ++ if (sta) { + arsta = ath11k_sta_to_arsta(sta); + arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) | --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -7,6 +7,47 @@ - #ifndef ATH11K_PEER_H - #define ATH11K_PEER_H +@@ -18,6 +18,47 @@ struct ppdu_user_delayba { + u32 resp_rate_flags; + }; +enum ath11k_ast_entry_type { + ATH11K_AST_TYPE_NONE, /* static ast entry for connected peer */ @@ -678,7 +677,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_peer { struct list_head list; struct ieee80211_sta *sta; -@@ -18,6 +59,10 @@ struct ath11k_peer { +@@ -29,6 +70,10 @@ struct ath11k_peer { u8 pdev_idx; u16 hw_peer_id; struct ath11k_nss_peer nss; @@ -689,7 +688,7 @@ Signed-off-by: Sathishkumar Muruganandam /* protected by ab->data_lock */ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; -@@ -41,8 +86,13 @@ struct ath11k_peer { +@@ -54,8 +99,13 @@ struct ath11k_peer { }; void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id); @@ -703,7 +702,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id, const u8 *addr); struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab, -@@ -59,4 +109,71 @@ struct ath11k_peer *ath11k_peer_find_by_ +@@ -73,4 +123,71 @@ struct ath11k_peer *ath11k_peer_find_by_ int ath11k_peer_rhash_tbl_init(struct ath11k_base *ab); void ath11k_peer_rhash_tbl_destroy(struct ath11k_base *ab); int ath11k_peer_rhash_delete(struct ath11k_base *ab, struct ath11k_peer *peer); @@ -777,15 +776,16 @@ Signed-off-by: Sathishkumar Muruganandam #endif /* _PEER_H_ */ --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -155,6 +155,7 @@ static const struct wmi_tlv_policy wmi_t - .min_len = sizeof(struct wmi_per_chain_rssi_stats), .policy = "wmi_per_chain_rssi_stats" }, +@@ -156,6 +156,8 @@ static const struct wmi_tlv_policy wmi_t + .min_len = sizeof(struct wmi_per_chain_rssi_stats) }, [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = { - .min_len = sizeof(struct wmi_twt_add_dialog_event), .policy = "wmi_twt_add_dialog_event" }, -+ [WMI_TAG_WDS_ADDR_EVENT] = { .min_len = sizeof(struct wmi_wds_addr_event), .policy = "wmi_wds_addr_event" }, + .min_len = sizeof(struct wmi_twt_add_dialog_event) }, ++ [WMI_TAG_WDS_ADDR_EVENT] = { ++ .min_len = sizeof(struct wmi_wds_addr_event) }, }; #define PRIMAP(_hw_mode_) \ -@@ -1174,6 +1175,51 @@ int ath11k_wmi_send_peer_delete_cmd(stru +@@ -1126,6 +1128,51 @@ int ath11k_wmi_send_peer_delete_cmd(stru return ret; } @@ -837,7 +837,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar, struct pdev_set_regdomain_params *param) { -@@ -6419,6 +6465,36 @@ static int ath11k_pull_peer_assoc_conf_e +@@ -6363,6 +6410,36 @@ static int ath11k_pull_peer_assoc_conf_e return 0; } @@ -874,7 +874,7 @@ Signed-off-by: Sathishkumar Muruganandam static void ath11k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src, struct ath11k_fw_stats_pdev *dst) { -@@ -7334,6 +7410,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru +@@ -7278,6 +7355,7 @@ static int ath11k_wmi_tlv_rdy_parse(stru ether_addr_copy(ab->mac_addr, fixed_param.ready_event_min.mac_addr.addr); @@ -882,7 +882,7 @@ Signed-off-by: Sathishkumar Muruganandam ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum; break; case WMI_TAG_ARRAY_FIXED_STRUCT: -@@ -8805,6 +8882,22 @@ static void ath11k_wmi_gtk_offload_statu +@@ -8797,6 +8875,22 @@ exit: kfree(tb); } @@ -905,9 +905,9 @@ Signed-off-by: Sathishkumar Muruganandam static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) { struct wmi_cmd_hdr *cmd_hdr; -@@ -8935,6 +9028,9 @@ static void ath11k_wmi_tlv_op_rx(struct - case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID: - ath11k_qos_null_compl_event(ab, skb); +@@ -8927,6 +9021,9 @@ static void ath11k_wmi_tlv_op_rx(struct + case WMI_GTK_OFFLOAD_STATUS_EVENTID: + ath11k_wmi_gtk_offload_status_event(ab, skb); break; + case WMI_WDS_PEER_EVENTID: + ath11k_wmi_wds_peer_event(ab, skb); @@ -917,7 +917,7 @@ Signed-off-by: Sathishkumar Muruganandam break; --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -3025,6 +3025,21 @@ struct wmi_peer_delete_cmd { +@@ -3011,6 +3011,21 @@ struct wmi_peer_delete_cmd { struct wmi_mac_addr peer_macaddr; } __packed; @@ -939,7 +939,7 @@ Signed-off-by: Sathishkumar Muruganandam struct wmi_peer_reorder_queue_setup_cmd { u32 tlv_header; u32 vdev_id; -@@ -4629,6 +4644,21 @@ struct wmi_probe_resp_tx_status_event { +@@ -4613,6 +4628,21 @@ struct wmi_probe_resp_tx_status_event { u32 tx_status; } __packed; @@ -961,7 +961,7 @@ Signed-off-by: Sathishkumar Muruganandam /* * PDEV statistics */ -@@ -6430,6 +6460,9 @@ int ath11k_wmi_set_sta_ps_param(struct a +@@ -6412,6 +6442,9 @@ int ath11k_wmi_set_sta_ps_param(struct a int ath11k_wmi_force_fw_hang_cmd(struct ath11k *ar, u32 type, u32 delay_time_ms); int ath11k_wmi_send_peer_delete_cmd(struct ath11k *ar, const u8 *peer_addr, u8 vdev_id); diff --git a/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch b/package/kernel/mac80211/patches/nss/ath11k/214-ath11k-qos-null-frame-tx-over-wmi.patch similarity index 59% rename from package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch rename to package/kernel/mac80211/patches/nss/ath11k/214-ath11k-qos-null-frame-tx-over-wmi.patch index a69c5b2af2..5f31f4ded2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/214-ath11k-qos-null-frame-tx-over-wmi.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/214-ath11k-qos-null-frame-tx-over-wmi.patch @@ -82,128 +82,16 @@ Signed-off-by: Sowmiya Sree Elavalagan if (control->sta) --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -23,6 +23,7 @@ - - struct wmi_tlv_policy { - size_t min_len; -+ char policy[40]; - }; - - struct wmi_tlv_svc_ready_parse { -@@ -91,69 +92,69 @@ struct wmi_tlv_mgmt_rx_parse { - - static const struct wmi_tlv_policy wmi_tlv_policies[] = { - [WMI_TAG_ARRAY_BYTE] -- = { .min_len = 0 }, -+ = { .min_len = 0, .policy = "WMI_TAG_ARRAY_BYTE" }, - [WMI_TAG_ARRAY_UINT32] -- = { .min_len = 0 }, -+ = { .min_len = 0, .policy = "WMI_TAG_ARRAY_UINT32" }, - [WMI_TAG_SERVICE_READY_EVENT] -- = { .min_len = sizeof(struct wmi_service_ready_event) }, -+ = { .min_len = sizeof(struct wmi_service_ready_event), .policy = "wmi_service_ready_event" }, - [WMI_TAG_SERVICE_READY_EXT_EVENT] -- = { .min_len = sizeof(struct wmi_service_ready_ext_event) }, -+ = { .min_len = sizeof(struct wmi_service_ready_ext_event), .policy = "wmi_service_ready_ext_event" }, - [WMI_TAG_SOC_MAC_PHY_HW_MODE_CAPS] -- = { .min_len = sizeof(struct wmi_soc_mac_phy_hw_mode_caps) }, -+ = { .min_len = sizeof(struct wmi_soc_mac_phy_hw_mode_caps), .policy = "wmi_soc_mac_phy_hw_mode_caps" }, - [WMI_TAG_SOC_HAL_REG_CAPABILITIES] -- = { .min_len = sizeof(struct wmi_soc_hal_reg_capabilities) }, -+ = { .min_len = sizeof(struct wmi_soc_hal_reg_capabilities), .policy = "wmi_soc_hal_reg_capabilities" }, - [WMI_TAG_VDEV_START_RESPONSE_EVENT] -- = { .min_len = sizeof(struct wmi_vdev_start_resp_event) }, -+ = { .min_len = sizeof(struct wmi_vdev_start_resp_event), .policy = "wmi_vdev_start_resp_event" }, - [WMI_TAG_PEER_DELETE_RESP_EVENT] -- = { .min_len = sizeof(struct wmi_peer_delete_resp_event) }, -+ = { .min_len = sizeof(struct wmi_peer_delete_resp_event), .policy = "wmi_peer_delete_resp_event" }, - [WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT] -- = { .min_len = sizeof(struct wmi_bcn_tx_status_event) }, -+ = { .min_len = sizeof(struct wmi_bcn_tx_status_event), .policy = "wmi_bcn_tx_status_event" }, - [WMI_TAG_VDEV_STOPPED_EVENT] -- = { .min_len = sizeof(struct wmi_vdev_stopped_event) }, -+ = { .min_len = sizeof(struct wmi_vdev_stopped_event), .policy = "wmi_vdev_stopped_event" }, - [WMI_TAG_REG_CHAN_LIST_CC_EVENT] -- = { .min_len = sizeof(struct wmi_reg_chan_list_cc_event) }, -+ = { .min_len = sizeof(struct wmi_reg_chan_list_cc_event), .policy = "wmi_reg_chan_list_cc_event" }, - [WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT] -- = { .min_len = sizeof(struct wmi_reg_chan_list_cc_ext_event) }, -+ = { .min_len = sizeof(struct wmi_reg_chan_list_cc_ext_event), .policy = "wmi_reg_chan_list_cc_ext_event" }, +@@ -117,7 +117,7 @@ static const struct wmi_tlv_policy wmi_t [WMI_TAG_MGMT_RX_HDR] -- = { .min_len = sizeof(struct wmi_mgmt_rx_hdr) }, -+ = { .min_len = sizeof(struct wmi_mgmt_rx_hdr), .policy = "wmi_mgmt_rx_hdr" }, + = { .min_len = sizeof(struct wmi_mgmt_rx_hdr) }, [WMI_TAG_MGMT_TX_COMPL_EVENT] - = { .min_len = sizeof(struct wmi_mgmt_tx_compl_event) }, -+ = { .min_len = sizeof(struct wmi_tx_compl_event), .policy = "wmi_tx_compl_event" }, ++ = { .min_len = sizeof(struct wmi_tx_compl_event) }, [WMI_TAG_SCAN_EVENT] -- = { .min_len = sizeof(struct wmi_scan_event) }, -+ = { .min_len = sizeof(struct wmi_scan_event), .policy = "wmi_scan_event" }, + = { .min_len = sizeof(struct wmi_scan_event) }, [WMI_TAG_PEER_STA_KICKOUT_EVENT] -- = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) }, -+ = { .min_len = sizeof(struct wmi_peer_sta_kickout_event), .policy = "wmi_peer_sta_kickout_event" }, - [WMI_TAG_ROAM_EVENT] -- = { .min_len = sizeof(struct wmi_roam_event) }, -+ = { .min_len = sizeof(struct wmi_roam_event), .policy = "wmi_roam_event" }, - [WMI_TAG_CHAN_INFO_EVENT] -- = { .min_len = sizeof(struct wmi_chan_info_event) }, -+ = { .min_len = sizeof(struct wmi_chan_info_event), .policy = "wmi_chan_info_event" }, - [WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT] -- = { .min_len = sizeof(struct wmi_pdev_bss_chan_info_event) }, -+ = { .min_len = sizeof(struct wmi_pdev_bss_chan_info_event), .policy = "wmi_pdev_bss_chan_info_event" }, - [WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT] -- = { .min_len = sizeof(struct wmi_vdev_install_key_compl_event) }, -+ = { .min_len = sizeof(struct wmi_vdev_install_key_compl_event), .policy = "wmi_vdev_install_key_compl_event" }, - [WMI_TAG_READY_EVENT] = { -- .min_len = sizeof(struct wmi_ready_event_min) }, -+ .min_len = sizeof(struct wmi_ready_event_min), .policy = "wmi_ready_event_min" }, - [WMI_TAG_SERVICE_AVAILABLE_EVENT] -- = {.min_len = sizeof(struct wmi_service_available_event) }, -+ = {.min_len = sizeof(struct wmi_service_available_event), .policy = "wmi_service_available_event" }, - [WMI_TAG_PEER_ASSOC_CONF_EVENT] -- = { .min_len = sizeof(struct wmi_peer_assoc_conf_event) }, -+ = { .min_len = sizeof(struct wmi_peer_assoc_conf_event), .policy = "wmi_peer_assoc_conf_event" }, - [WMI_TAG_STATS_EVENT] -- = { .min_len = sizeof(struct wmi_stats_event) }, -+ = { .min_len = sizeof(struct wmi_stats_event), .policy = "wmi_stats_event" }, - [WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT] -- = { .min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event) }, -+ = { .min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event), .policy = "wmi_pdev_ctl_failsafe_chk_event" }, - [WMI_TAG_HOST_SWFDA_EVENT] = { -- .min_len = sizeof(struct wmi_fils_discovery_event) }, -+ .min_len = sizeof(struct wmi_fils_discovery_event), .policy = "wmi_fils_discovery_event" }, - [WMI_TAG_OFFLOAD_PRB_RSP_TX_STATUS_EVENT] = { -- .min_len = sizeof(struct wmi_probe_resp_tx_status_event) }, -+ .min_len = sizeof(struct wmi_probe_resp_tx_status_event), .policy = "wmi_probe_resp_tx_status_event" }, - [WMI_TAG_VDEV_DELETE_RESP_EVENT] = { -- .min_len = sizeof(struct wmi_vdev_delete_resp_event) }, -+ .min_len = sizeof(struct wmi_vdev_delete_resp_event), .policy = "wmi_vdev_delete_resp_event" }, - [WMI_TAG_OBSS_COLOR_COLLISION_EVT] = { -- .min_len = sizeof(struct wmi_obss_color_collision_event) }, -+ .min_len = sizeof(struct wmi_obss_color_collision_event), .policy = "wmi_obss_color_collision_event" }, - [WMI_TAG_11D_NEW_COUNTRY_EVENT] = { -- .min_len = sizeof(struct wmi_11d_new_cc_ev) }, -+ .min_len = sizeof(struct wmi_11d_new_cc_ev), .policy = "wmi_11d_new_cc_ev" }, - [WMI_TAG_PER_CHAIN_RSSI_STATS] = { -- .min_len = sizeof(struct wmi_per_chain_rssi_stats) }, -+ .min_len = sizeof(struct wmi_per_chain_rssi_stats), .policy = "wmi_per_chain_rssi_stats" }, - [WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = { -- .min_len = sizeof(struct wmi_twt_add_dialog_event) }, -+ .min_len = sizeof(struct wmi_twt_add_dialog_event), .policy = "wmi_twt_add_dialog_event" }, - }; - - #define PRIMAP(_hw_mode_) \ -@@ -203,8 +204,8 @@ ath11k_wmi_tlv_iter(struct ath11k_base * - if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) && - wmi_tlv_policies[tlv_tag].min_len && - wmi_tlv_policies[tlv_tag].min_len > tlv_len) { -- ath11k_err(ab, "wmi tlv parse failure of tag %u at byte %zd (%u bytes is less than min length %zu)\n", -- tlv_tag, ptr - begin, tlv_len, -+ ath11k_err(ab, "wmi tlv parse failure of tag %u (%s) at byte %zd (%u bytes is less than min length %zu)\n", -+ tlv_tag, wmi_tlv_policies[tlv_tag].policy, ptr - begin, tlv_len, - wmi_tlv_policies[tlv_tag].min_len); - return -EINVAL; - } -@@ -697,6 +698,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * +@@ -701,6 +701,55 @@ int ath11k_wmi_mgmt_send(struct ath11k * return ret; } @@ -259,15 +147,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr, struct vdev_create_params *param) { -@@ -4103,7 +4153,6 @@ ath11k_wmi_copy_resource_config(struct w - wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters; - wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id; - wmi_cfg->flag1 = tg_cfg->flag1; -- wmi_cfg->flag1 |= WMI_RSRC_CFG_FLAG1_ACK_RSSI; - wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support; - wmi_cfg->sched_params = tg_cfg->sched_params; - wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; -@@ -5856,8 +5905,8 @@ static int ath11k_pull_mgmt_rx_params_tl +@@ -5905,8 +5954,8 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } @@ -278,7 +158,7 @@ Signed-off-by: Sowmiya Sree Elavalagan { struct sk_buff *msdu; struct ieee80211_tx_info *info; -@@ -5895,6 +5944,11 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5944,6 +5993,11 @@ static int wmi_process_mgmt_tx_comp(stru info->status.ack_signal = tx_compl_param->ack_rssi; } @@ -290,7 +170,7 @@ Signed-off-by: Sowmiya Sree Elavalagan hdr = (struct ieee80211_hdr *)msdu->data; frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); -@@ -5913,10 +5967,13 @@ static int wmi_process_mgmt_tx_comp(stru +@@ -5962,10 +6016,13 @@ static int wmi_process_mgmt_tx_comp(stru arvif = ath11k_vif_to_arvif(vif); mgmt_stats = &arvif->mgmt_stats; @@ -308,7 +188,7 @@ Signed-off-by: Sowmiya Sree Elavalagan spin_unlock_bh(&ar->data_lock); skip_mgmt_stats: -@@ -5938,12 +5995,13 @@ skip_mgmt_stats: +@@ -5987,12 +6044,13 @@ skip_mgmt_stats: return 0; } @@ -326,7 +206,7 @@ Signed-off-by: Sowmiya Sree Elavalagan int ret; tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); -@@ -5953,7 +6011,7 @@ static int ath11k_pull_mgmt_tx_compl_par +@@ -6002,7 +6060,7 @@ static int ath11k_pull_mgmt_tx_compl_par return ret; } @@ -335,7 +215,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (!ev) { ath11k_warn(ab, "failed to fetch mgmt tx compl ev"); kfree(tb); -@@ -7730,10 +7788,11 @@ exit: +@@ -7810,10 +7868,11 @@ exit: static void ath11k_mgmt_tx_compl_event(struct ath11k_base *ab, struct sk_buff *skb) { @@ -349,7 +229,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ath11k_warn(ab, "failed to extract mgmt tx compl event"); return; } -@@ -7746,7 +7805,7 @@ static void ath11k_mgmt_tx_compl_event(s +@@ -7826,7 +7885,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } @@ -358,7 +238,7 @@ Signed-off-by: Sowmiya Sree Elavalagan ath11k_dbg(ab, ATH11K_DBG_MGMT, "event mgmt tx compl ev pdev_id %d, desc_id %d, status %d ack_rssi %d", -@@ -7757,6 +7816,36 @@ exit: +@@ -7837,6 +7896,36 @@ exit: rcu_read_unlock(); } @@ -395,13 +275,14 @@ Signed-off-by: Sowmiya Sree Elavalagan static struct ath11k *ath11k_get_ar_on_scan_state(struct ath11k_base *ab, u32 vdev_id, enum ath11k_scan_state state) -@@ -8843,6 +8932,9 @@ static void ath11k_wmi_tlv_op_rx(struct - case WMI_GTK_OFFLOAD_STATUS_EVENTID: - ath11k_wmi_gtk_offload_status_event(ab, skb); +@@ -9024,6 +9113,10 @@ static void ath11k_wmi_tlv_op_rx(struct + case WMI_WDS_PEER_EVENTID: + ath11k_wmi_wds_peer_event(ab, skb); break; + case WMI_QOS_NULL_FRAME_TX_COMPLETION_EVENTID: + ath11k_qos_null_compl_event(ab, skb); + break; ++ default: ath11k_dbg(ab, ATH11K_DBG_WMI, "unsupported event id 0x%x\n", id); break; @@ -425,16 +306,16 @@ Signed-off-by: Sowmiya Sree Elavalagan WMI_TX_ADDBA_COMPLETE_EVENTID, WMI_BA_RSP_SSN_EVENTID, @@ -1880,6 +1883,9 @@ enum wmi_tlv_tag { + WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, + WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9, WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT, - WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8, - WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD, + /* TODO add all the missing cmds */ + WMI_TAG_QOS_NULL_FRAME_TX_SEND = 0x3A6, + WMI_TAG_QOS_NULL_FRAME_TX_STATUS, + WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8, + WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD, WMI_TAG_MAX - }; - -@@ -2107,7 +2113,17 @@ enum wmi_tlv_service { +@@ -2109,7 +2115,17 @@ enum wmi_tlv_service { WMI_TLV_SERVICE_PEER_POWER_SAVE_DURATION_SUPPORT = 246, WMI_TLV_SERVICE_SRG_SRP_SPATIAL_REUSE_SUPPORT = 249, WMI_TLV_SERVICE_MBSS_PARAM_IN_VDEV_START_SUPPORT = 253, @@ -452,7 +333,7 @@ Signed-off-by: Sowmiya Sree Elavalagan /* The second 128 bits */ WMI_MAX_EXT_SERVICE = 256, -@@ -3814,6 +3830,7 @@ struct wmi_scan_prob_req_oui_cmd { +@@ -3831,6 +3847,7 @@ struct wmi_scan_prob_req_oui_cmd { } __packed; #define WMI_MGMT_SEND_DOWNLD_LEN 64 @@ -460,7 +341,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_TX_PARAMS_DWORD0_POWER GENMASK(7, 0) #define WMI_TX_PARAMS_DWORD0_MCS_MASK GENMASK(19, 8) -@@ -3824,9 +3841,10 @@ struct wmi_scan_prob_req_oui_cmd { +@@ -3841,9 +3858,10 @@ struct wmi_scan_prob_req_oui_cmd { #define WMI_TX_PARAMS_DWORD1_BW_MASK GENMASK(14, 8) #define WMI_TX_PARAMS_DWORD1_PREAMBLE_TYPE GENMASK(19, 15) #define WMI_TX_PARAMS_DWORD1_FRAME_TYPE BIT(20) @@ -473,15 +354,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 tlv_header; u32 tx_params_dword0; u32 tx_params_dword1; -@@ -4570,7 +4588,6 @@ struct wmi_pdev_bss_chan_info_event { - u32 rx_bss_cycle_count_low; - u32 rx_bss_cycle_count_high; - u32 pdev_id; -- u32 ack_rssi; - } __packed; - - #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0 -@@ -4918,7 +4935,7 @@ struct wmi_rssi_ctl_ext { +@@ -4959,7 +4977,7 @@ struct wmi_rssi_ctl_ext { u32 rssi_ctl_ext[MAX_ANTENNA_EIGHT - ATH_MAX_ANTENNA]; }; @@ -490,7 +363,7 @@ Signed-off-by: Sowmiya Sree Elavalagan u32 desc_id; u32 status; u32 pdev_id; -@@ -5748,6 +5765,17 @@ struct wmi_debug_log_config_cmd_fixed_pa +@@ -5790,6 +5808,17 @@ struct wmi_debug_log_config_cmd_fixed_pa u32 value; } __packed; @@ -508,7 +381,7 @@ Signed-off-by: Sowmiya Sree Elavalagan #define WMI_MAX_MEM_REQS 32 #define MAX_RADIOS 3 -@@ -6358,6 +6386,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pd +@@ -6400,6 +6429,8 @@ int ath11k_wmi_cmd_send(struct ath11k_pd struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id, struct sk_buff *frame); diff --git a/package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch b/package/kernel/mac80211/patches/nss/ath11k/235-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch similarity index 93% rename from package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch rename to package/kernel/mac80211/patches/nss/ath11k/235-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch index 6f5fffe596..7a93596826 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/903-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/235-002-ath11k-add-support-for-ext-vdev-in-NSS-for-AP_VLAN-vif-handling.patch @@ -17,7 +17,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -366,6 +366,10 @@ void ath11k_nss_wifili_event_receive(str +@@ -323,6 +323,10 @@ void ath11k_nss_wifili_event_receive(str ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili wds peer del event received %d response %d error %d\n", msg_type, response, error); break; @@ -28,7 +28,7 @@ Signed-off-by: Sathishkumar Muruganandam default: ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); break; -@@ -599,8 +603,9 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -556,8 +560,9 @@ static int ath11k_nss_undecap_nwifi(stru return 0; } @@ -40,7 +40,7 @@ Signed-off-by: Sathishkumar Muruganandam { struct ath11k_base *ab = ar->ab; struct ath11k_ast_entry *ast_entry = NULL; -@@ -622,19 +627,22 @@ static void ath11k_nss_wds_type_rx(struc +@@ -579,19 +584,22 @@ static void ath11k_nss_wds_type_rx(struc if (!is_sa_valid) { ath11k_peer_add_ast(ar, ta_peer, src_mac, ATH11K_AST_TYPE_WDS); @@ -68,7 +68,7 @@ Signed-off-by: Sathishkumar Muruganandam } spin_unlock_bh(&ab->base_lock); -@@ -678,7 +686,8 @@ static void ath11k_nss_mec_handler(struc +@@ -635,7 +643,8 @@ static void ath11k_nss_mec_handler(struc static void ath11k_nss_vdev_spl_receive_ext_wdsdata(struct ath11k_vif *arvif, struct sk_buff *skb, @@ -78,7 +78,7 @@ Signed-off-by: Sathishkumar Muruganandam { struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; -@@ -699,8 +708,8 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -656,8 +665,8 @@ static void ath11k_nss_vdev_spl_receive_ switch (wds_type) { case NSS_WIFI_VDEV_WDS_TYPE_RX: @@ -89,7 +89,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); -@@ -767,6 +776,7 @@ ath11k_nss_vdev_special_data_receive(str +@@ -724,6 +733,7 @@ ath11k_nss_vdev_special_data_receive(str struct ieee80211_vif *vif; struct ath11k_vif *arvif; struct ath11k_base *ab; @@ -97,7 +97,7 @@ Signed-off-by: Sathishkumar Muruganandam bool eth_decap = false; int data_offs = 0; int ret = 0; -@@ -822,10 +832,11 @@ ath11k_nss_vdev_special_data_receive(str +@@ -779,10 +789,11 @@ ath11k_nss_vdev_special_data_receive(str NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN) { wds_metadata = &wifi_metadata->metadata.wds_metadata; ath11k_nss_vdev_spl_receive_ext_wdsdata(arvif, skb, @@ -111,7 +111,7 @@ Signed-off-by: Sathishkumar Muruganandam } static void -@@ -888,6 +899,68 @@ ath11k_nss_vdev_data_receive(struct net_ +@@ -845,6 +856,68 @@ ath11k_nss_vdev_data_receive(struct net_ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); } @@ -180,7 +180,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) { struct ath11k *ar = arvif->ar; -@@ -910,10 +983,16 @@ int ath11k_nss_tx(struct ath11k_vif *arv +@@ -867,10 +940,16 @@ int ath11k_nss_tx(struct ath11k_vif *arv ath11k_nss_tx_encap_nwifi(skb); send: @@ -201,7 +201,7 @@ Signed-off-by: Sathishkumar Muruganandam if (status != NSS_TX_SUCCESS) { ath11k_dbg(ar->ab, (ATH11K_DBG_NSS | ATH11K_DBG_DP_TX), -@@ -1254,6 +1333,7 @@ int ath11k_nss_vdev_up(struct ath11k_vif +@@ -1211,6 +1290,7 @@ int ath11k_nss_vdev_up(struct ath11k_vif struct nss_wifi_vdev_msg *vdev_msg = NULL; struct nss_wifi_vdev_enable_msg *vdev_en; struct ath11k *ar = arvif->ar; @@ -209,7 +209,7 @@ Signed-off-by: Sathishkumar Muruganandam nss_tx_status_t status; int ret = 0; -@@ -1285,6 +1365,12 @@ int ath11k_nss_vdev_up(struct ath11k_vif +@@ -1242,6 +1322,12 @@ int ath11k_nss_vdev_up(struct ath11k_vif } ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev up tx msg success\n"); @@ -222,7 +222,7 @@ Signed-off-by: Sathishkumar Muruganandam free: kfree(vdev_msg); return ret; -@@ -1294,6 +1380,7 @@ int ath11k_nss_vdev_down(struct ath11k_v +@@ -1251,6 +1337,7 @@ int ath11k_nss_vdev_down(struct ath11k_v { struct nss_wifi_vdev_msg *vdev_msg = NULL; struct ath11k *ar = arvif->ar; @@ -230,7 +230,7 @@ Signed-off-by: Sathishkumar Muruganandam nss_tx_status_t status; int ret = 0; -@@ -1321,11 +1408,362 @@ int ath11k_nss_vdev_down(struct ath11k_v +@@ -1278,11 +1365,362 @@ int ath11k_nss_vdev_down(struct ath11k_v } ath11k_dbg(ar->ab, ATH11K_DBG_NSS, "nss vdev down tx msg success\n"); @@ -262,7 +262,7 @@ Signed-off-by: Sathishkumar Muruganandam + + cfg_wds_msg = &ext_vdev_msg->msg.wmsg; + cfg_wds_msg->wds_peer_id = wds_peer_id; -+ ether_addr_copy(cfg_wds_msg->mac_addr, wds_addr); ++ ether_addr_copy((u8 *)cfg_wds_msg->mac_addr, wds_addr); + + nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, + NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS, @@ -593,7 +593,7 @@ Signed-off-by: Sathishkumar Muruganandam /*----------------------------Peer Setup/Config -----------------------------*/ int ath11k_nss_set_peer_sec_type(struct ath11k *ar, -@@ -1419,22 +1857,22 @@ free: +@@ -1376,22 +1814,22 @@ free: return status; } @@ -623,7 +623,7 @@ Signed-off-by: Sathishkumar Muruganandam sta->addr); goto exit; } -@@ -1506,13 +1944,13 @@ void ath11k_nss_update_sta_rxrate(struct +@@ -1463,13 +1901,13 @@ void ath11k_nss_update_sta_rxrate(struct struct ath11k_peer *peer, struct hal_rx_user_status *user_stats) { @@ -639,7 +639,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_base *ab = ar->ab; if (!ab->nss.enabled) -@@ -1816,8 +2254,8 @@ int ath11k_nss_add_wds_peer(struct ath11 +@@ -1773,8 +2211,8 @@ int ath11k_nss_add_wds_peer(struct ath11 } ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, @@ -650,7 +650,7 @@ Signed-off-by: Sathishkumar Muruganandam msg_free: kfree(wlmsg); -@@ -1862,8 +2300,8 @@ int ath11k_nss_update_wds_peer(struct at +@@ -1819,8 +2257,8 @@ int ath11k_nss_update_wds_peer(struct at } ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, @@ -663,7 +663,7 @@ Signed-off-by: Sathishkumar Muruganandam kfree(wlmsg); --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -154,6 +154,7 @@ enum ath11k_nss_peer_sec_type { +@@ -151,6 +151,7 @@ enum ath11k_nss_peer_sec_type { struct ath11k_nss_peer { uint32_t *vaddr; dma_addr_t paddr; @@ -671,7 +671,7 @@ Signed-off-by: Sathishkumar Muruganandam struct peer_stats *nss_stats; struct completion complete; }; -@@ -168,6 +169,16 @@ struct arvif_nss { +@@ -165,6 +166,16 @@ struct arvif_nss { int encap; /* Keep the copy of decap type for nss */ int decap; @@ -688,7 +688,7 @@ Signed-off-by: Sathishkumar Muruganandam bool created; }; -@@ -223,11 +234,21 @@ int ath11k_nss_map_wds_peer(struct ath11 +@@ -220,11 +231,21 @@ int ath11k_nss_map_wds_peer(struct ath11 u8 *dest_mac, enum ath11k_ast_entry_type type); int ath11k_nss_del_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, u8 *dest_mac); @@ -713,7 +713,7 @@ Signed-off-by: Sathishkumar Muruganandam void ath11k_nss_update_sta_rxrate(struct hal_rx_mon_ppdu_info *ppdu_info, struct ath11k_peer *peer, struct hal_rx_user_status *user_stats); -@@ -260,9 +281,9 @@ static inline void ath11k_nss_vdev_delet +@@ -257,9 +278,9 @@ static inline void ath11k_nss_vdev_delet { } @@ -726,7 +726,7 @@ Signed-off-by: Sathishkumar Muruganandam { return; } -@@ -319,6 +340,43 @@ static inline int ath11k_nss_peer_create +@@ -316,6 +337,43 @@ static inline int ath11k_nss_peer_create return 0; } @@ -770,7 +770,7 @@ Signed-off-by: Sathishkumar Muruganandam static inline void ath11k_nss_peer_stats_enable(struct ath11k *ar) { return; -@@ -340,6 +398,11 @@ static inline int ath11k_nss_setup(struc +@@ -337,6 +395,11 @@ static inline int ath11k_nss_setup(struc return 0; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch b/package/kernel/mac80211/patches/nss/ath11k/235-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch similarity index 89% rename from package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch rename to package/kernel/mac80211/patches/nss/ath11k/235-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch index de7bc77ef5..1730beea85 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/903-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/235-003-ath11k-add-AP_VLAN-vif-support-for-WDS-offload-in-NSS-offload.patch @@ -33,13 +33,10 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -385,9 +385,8 @@ struct ath11k_vif { - #endif /* CPTCFG_ATH11K_DEBUGFS */ - - struct ath11k_mgmt_frame_stats mgmt_stats; --#ifdef CPTCFG_ATH11K_NSS_SUPPORT +@@ -389,6 +389,7 @@ struct ath11k_vif { + #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct arvif_nss nss; --#endif + #endif + struct list_head ap_vlan_arvifs; }; @@ -184,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif, -@@ -5278,9 +5379,32 @@ static void ath11k_mac_op_sta_set_4addr( +@@ -5259,9 +5360,32 @@ static void ath11k_mac_op_sta_set_4addr( struct ieee80211_sta *sta, bool enabled) { struct ath11k *ar = hw->priv; @@ -217,7 +214,7 @@ Signed-off-by: Sathishkumar Muruganandam ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk); arsta->use_4addr_set = true; } -@@ -6673,6 +6797,9 @@ static int ath11k_mac_op_update_vif_offl +@@ -6641,6 +6765,9 @@ static int ath11k_mac_op_update_vif_offl u32 param_id, param_value; int ret; @@ -227,7 +224,7 @@ Signed-off-by: Sathishkumar Muruganandam param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE; if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET || (vif->type != NL80211_IFTYPE_STATION && -@@ -6893,7 +7020,8 @@ static int ath11k_mac_op_add_interface(s +@@ -6861,7 +6988,8 @@ static int ath11k_mac_op_add_interface(s goto err; } @@ -237,7 +234,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_warn(ab, "failed to create vdev %u, reached max vdev limit %d\n", ar->num_created_vdevs, TARGET_NUM_VDEVS(ab)); ret = -EBUSY; -@@ -6913,6 +7041,28 @@ static int ath11k_mac_op_add_interface(s +@@ -6881,6 +7009,28 @@ static int ath11k_mac_op_add_interface(s arvif->vif = vif; INIT_LIST_HEAD(&arvif->list); @@ -266,7 +263,7 @@ Signed-off-by: Sathishkumar Muruganandam INIT_DELAYED_WORK(&arvif->connection_loss_work, ath11k_mac_vif_sta_connection_loss_work); -@@ -6942,6 +7092,7 @@ static int ath11k_mac_op_add_interface(s +@@ -6910,6 +7060,7 @@ static int ath11k_mac_op_add_interface(s fallthrough; case NL80211_IFTYPE_AP: arvif->vdev_type = WMI_VDEV_TYPE_AP; @@ -274,7 +271,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case NL80211_IFTYPE_MONITOR: arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; -@@ -7164,13 +7315,30 @@ static void ath11k_mac_op_remove_interfa +@@ -7132,13 +7283,30 @@ static void ath11k_mac_op_remove_interfa struct ath11k *ar = hw->priv; struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); struct ath11k_base *ab = ar->ab; @@ -307,7 +304,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "remove interface (vdev %d)\n", arvif->vdev_id); -@@ -7187,6 +7355,14 @@ static void ath11k_mac_op_remove_interfa +@@ -7155,6 +7323,14 @@ static void ath11k_mac_op_remove_interfa if (ret) ath11k_warn(ab, "failed to submit AP self-peer removal on vdev %d: %d\n", arvif->vdev_id, ret); @@ -322,7 +319,7 @@ Signed-off-by: Sathishkumar Muruganandam } ret = ath11k_mac_vdev_delete(ar, arvif); -@@ -7230,8 +7406,7 @@ err_vdev_del: +@@ -7198,8 +7374,7 @@ err_vdev_del: ath11k_debugfs_remove_interface(arvif); @@ -332,7 +329,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); } -@@ -7291,16 +7466,17 @@ static int ath11k_mac_op_ampdu_action(st +@@ -7259,16 +7434,17 @@ static int ath11k_mac_op_ampdu_action(st struct ieee80211_ampdu_params *params) { struct ath11k *ar = hw->priv; @@ -352,7 +349,7 @@ Signed-off-by: Sathishkumar Muruganandam break; case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_STOP_CONT: -@@ -8823,6 +8999,7 @@ static void ath11k_mac_op_sta_statistics +@@ -8791,6 +8967,7 @@ static void ath11k_mac_op_sta_statistics { struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); struct ath11k *ar = arsta->arvif->ar; @@ -360,7 +357,7 @@ Signed-off-by: Sathishkumar Muruganandam s8 signal; bool db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); -@@ -8879,7 +9056,8 @@ static void ath11k_mac_op_sta_statistics +@@ -8847,7 +9024,8 @@ static void ath11k_mac_op_sta_statistics ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); @@ -372,7 +369,7 @@ Signed-off-by: Sathishkumar Muruganandam #if IS_ENABLED(CONFIG_IPV6) --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -5069,6 +5069,8 @@ enum wmi_vdev_subtype { +@@ -5082,6 +5082,8 @@ enum wmi_vdev_subtype { WMI_VDEV_SUBTYPE_MESH_11S, }; @@ -383,7 +380,7 @@ Signed-off-by: Sathishkumar Muruganandam WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD = 1, --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -1162,12 +1162,13 @@ err_mem_free: +@@ -1121,12 +1121,13 @@ err_mem_free: return ret; } @@ -399,7 +396,7 @@ Signed-off-by: Sathishkumar Muruganandam int ret; ret = ath11k_peer_rx_tid_setup(ar, params->sta->addr, vdev_id, -@@ -1179,13 +1180,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 +@@ -1138,13 +1139,13 @@ int ath11k_dp_rx_ampdu_start(struct ath1 return ret; } @@ -418,9 +415,9 @@ Signed-off-by: Sathishkumar Muruganandam int ret; --- a/drivers/net/wireless/ath/ath11k/dp_rx.h +++ b/drivers/net/wireless/ath/ath11k/dp_rx.h -@@ -69,9 +69,9 @@ struct ath11k_dp_rfc1042_hdr { - __be16 snap_type; - } __packed; +@@ -88,9 +88,9 @@ static inline u32 ath11k_he_gi_to_nl8021 + return ret; + } -int ath11k_dp_rx_ampdu_start(struct ath11k *ar, +int ath11k_dp_rx_ampdu_start(struct ath11k_vif *arvif, @@ -432,7 +429,7 @@ Signed-off-by: Sathishkumar Muruganandam const u8 *peer_addr, --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c -@@ -126,6 +126,24 @@ struct ath11k_ast_entry *ath11k_peer_ast +@@ -140,6 +140,24 @@ struct ath11k_ast_entry *ath11k_peer_ast return NULL; } @@ -457,7 +454,7 @@ Signed-off-by: Sathishkumar Muruganandam void ath11k_peer_ast_wds_wmi_wk(struct work_struct *wk) { struct ath11k_ast_entry *ast_entry = container_of(wk, -@@ -186,8 +204,8 @@ int ath11k_peer_add_ast(struct ath11k *a +@@ -200,8 +218,8 @@ int ath11k_peer_add_ast(struct ath11k *a } if (type != ATH11K_AST_TYPE_STATIC) { @@ -468,7 +465,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_dbg(ab, ATH11K_DBG_MAC, "ast_entry %pM already present on peer %pM\n", mac_addr, ast_entry->peer->addr); return 0; -@@ -284,7 +302,6 @@ int ath11k_peer_update_ast(struct ath11k +@@ -298,7 +316,6 @@ int ath11k_peer_update_ast(struct ath11k ath11k_dbg(ab, ATH11K_DBG_MAC, "ath11k_peer_update_ast old peer %pM new peer %pM ast_entry %pM\n", old_peer->addr, peer->addr, ast_entry->addr); @@ -476,7 +473,7 @@ Signed-off-by: Sathishkumar Muruganandam ast_entry->action = ATH11K_WDS_WMI_UPDATE; ieee80211_queue_work(ar->hw, &ast_entry->wds_wmi_wk); -@@ -329,8 +346,8 @@ void ath11k_peer_del_ast(struct ath11k * +@@ -343,8 +360,8 @@ void ath11k_peer_del_ast(struct ath11k * peer = ast_entry->peer; @@ -489,7 +486,7 @@ Signed-off-by: Sathishkumar Muruganandam list_del(&ast_entry->ase_list); --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -23,6 +23,7 @@ enum ath11k_ast_entry_type { +@@ -34,6 +34,7 @@ enum ath11k_ast_entry_type { enum ath11k_wds_wmi_action { ATH11K_WDS_WMI_ADD = 1, ATH11K_WDS_WMI_UPDATE, @@ -497,7 +494,7 @@ Signed-off-by: Sathishkumar Muruganandam ATH11K_WDS_WMI_MAX }; -@@ -126,6 +127,8 @@ int ath11k_peer_rhash_delete(struct ath1 +@@ -127,6 +128,8 @@ int ath11k_peer_rhash_delete(struct ath1 #ifdef CPTCFG_ATH11K_NSS_SUPPORT struct ath11k_ast_entry *ath11k_peer_ast_find_by_addr(struct ath11k_base *ab, u8* addr); @@ -506,7 +503,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_peer_add_ast(struct ath11k *ar, struct ath11k_peer *peer, u8* mac_addr, enum ath11k_ast_entry_type type); int ath11k_peer_update_ast(struct ath11k *ar, struct ath11k_peer *peer, -@@ -145,6 +148,12 @@ static inline struct ath11k_ast_entry *a +@@ -146,6 +149,12 @@ static inline struct ath11k_ast_entry *a { return NULL; } @@ -521,7 +518,7 @@ Signed-off-by: Sathishkumar Muruganandam u8* mac_addr, enum ath11k_ast_entry_type type) --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -164,7 +164,10 @@ static void ath11k_nss_get_peer_stats(st +@@ -124,7 +124,10 @@ static void ath11k_nss_get_peer_stats(st peer->nss.nss_stats->tx_failed += tx_dropped; @@ -533,19 +530,19 @@ Signed-off-by: Sathishkumar Muruganandam rx_packets = pstats->rx.rx_recvd; peer->nss.nss_stats->rx_packets += rx_packets; -@@ -174,7 +177,10 @@ static void ath11k_nss_get_peer_stats(st +@@ -134,7 +137,10 @@ static void ath11k_nss_get_peer_stats(st pstats->rx.err.decrypt_err; peer->nss.nss_stats->rx_dropped += rx_dropped; - ATH11K_NSS_TXRX_NETDEV_STATS(rx, peer->vif, rx_bytes, rx_packets); + if (peer->nss.ext_vdev_up) -+ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->nss.ext_vif, tx_bytes, tx_packets); ++ ATH11K_NSS_TXRX_NETDEV_STATS(tx, peer->nss.ext_vif, rx_bytes, rx_packets); + else + ATH11K_NSS_TXRX_NETDEV_STATS(rx, peer->vif, rx_bytes, rx_packets); spin_unlock_bh(&ab->base_lock); rcu_read_unlock(); -@@ -1040,6 +1046,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -997,6 +1003,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 case ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD: cmd = NSS_WIFI_VDEV_DECAP_TYPE_CMD; break; @@ -557,15 +554,15 @@ Signed-off-by: Sathishkumar Muruganandam } --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -109,6 +109,7 @@ enum ath11k_nss_vdev_cmd { +@@ -108,6 +108,7 @@ enum ath11k_nss_vdev_cmd { ATH11K_NSS_WIFI_VDEV_SECURITY_TYPE_CMD, ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD, ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, + ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD, }; - #define WIFILI_SCHEME_ID_INVALID -1 -@@ -155,6 +156,7 @@ struct ath11k_nss_peer { + enum ath11k_nss_opmode { +@@ -152,6 +153,7 @@ struct ath11k_nss_peer { uint32_t *vaddr; dma_addr_t paddr; bool ext_vdev_up; diff --git a/package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch b/package/kernel/mac80211/patches/nss/ath11k/236-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch similarity index 92% rename from package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch rename to package/kernel/mac80211/patches/nss/ath11k/236-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch index 14274b6a72..cb1e39f149 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/904-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/236-002-ath11k-extend-ext-vdev-in-NSS-for-dynamic-VLAN-handling.patch @@ -15,7 +15,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -1570,14 +1570,11 @@ static int ath11k_nss_ext_vdev_register( +@@ -1527,14 +1527,11 @@ static int ath11k_nss_ext_vdev_register( struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; nss_tx_status_t status; @@ -30,7 +30,7 @@ Signed-off-by: Sathishkumar Muruganandam arvif->nss.ctx = nss_wifi_ext_vdev_register_if(arvif->nss.if_num, ath11k_nss_ext_vdev_data_receive, ath11k_nss_ext_vdev_special_data_receive, -@@ -1605,7 +1602,8 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1562,7 +1559,8 @@ static void ath11k_nss_ext_vdev_free(str status = nss_dynamic_interface_dealloc_node( arvif->nss.if_num, @@ -40,7 +40,7 @@ Signed-off-by: Sathishkumar Muruganandam if (status != NSS_TX_SUCCESS) ath11k_warn(ab, "failed to free nss ext vdev err:%d\n", status); -@@ -1614,14 +1612,19 @@ static void ath11k_nss_ext_vdev_free(str +@@ -1571,14 +1569,19 @@ static void ath11k_nss_ext_vdev_free(str "nss ext vdev interface deallocated\n"); } @@ -62,7 +62,7 @@ Signed-off-by: Sathishkumar Muruganandam if_num = nss_dynamic_interface_alloc_node(di_type); if (if_num < 0) { ath11k_warn(ab, "failed to allocate nss ext vdev\n"); -@@ -1630,8 +1633,8 @@ static int ath11k_nss_ext_vdev_alloc(str +@@ -1587,8 +1590,8 @@ static int ath11k_nss_ext_vdev_alloc(str arvif->nss.if_num = if_num; ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, @@ -73,7 +73,7 @@ Signed-off-by: Sathishkumar Muruganandam return 0; } -@@ -1660,7 +1663,7 @@ int ath11k_nss_ext_vdev_create(struct at +@@ -1617,7 +1620,7 @@ int ath11k_nss_ext_vdev_create(struct at return -EINVAL; } @@ -82,7 +82,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ret) return ret; -@@ -1773,6 +1776,86 @@ free: +@@ -1730,6 +1733,86 @@ free: return ret; } @@ -171,7 +171,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_nss_set_peer_sec_type(struct ath11k *ar, --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -179,6 +179,10 @@ struct arvif_nss { +@@ -176,6 +176,10 @@ struct arvif_nss { bool added; /* Flag to notify if ext vdev is up/down */ bool ext_vdev_up; @@ -182,7 +182,7 @@ Signed-off-by: Sathishkumar Muruganandam /* WDS cfg should be done only once for ext vdev */ bool wds_cfg_done; bool created; -@@ -246,6 +250,9 @@ void ath11k_nss_ext_vdev_unregister(stru +@@ -243,6 +247,9 @@ void ath11k_nss_ext_vdev_unregister(stru int ath11k_nss_ext_vdev_up(struct ath11k_vif *arvif); int ath11k_nss_ext_vdev_down(struct ath11k_vif *arvif); void ath11k_nss_ext_vdev_delete(struct ath11k_vif *arvif); @@ -192,7 +192,7 @@ Signed-off-by: Sathishkumar Muruganandam int ath11k_nss_set_peer_sec_type(struct ath11k *ar, struct ath11k_peer *peer, struct ieee80211_key_conf *key_conf); void ath11k_nss_update_sta_stats(struct ath11k_vif *arvif, -@@ -378,6 +385,18 @@ static inline int ath11k_nss_ext_vdev_do +@@ -375,6 +382,18 @@ static inline int ath11k_nss_ext_vdev_do { return 0; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch b/package/kernel/mac80211/patches/nss/ath11k/236-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch similarity index 91% rename from package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch rename to package/kernel/mac80211/patches/nss/ath11k/236-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch index 2361523d39..750fd2b239 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/904-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/236-003-ath11k-add-dynamic-VLAN-support-in-NSS-offload.patch @@ -36,7 +36,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -98,6 +98,11 @@ enum ath11k_crypt_mode { +@@ -99,6 +99,11 @@ enum ath11k_crypt_mode { ATH11K_CRYPT_MODE_SW, }; @@ -48,7 +48,7 @@ Signed-off-by: Sathishkumar Muruganandam static inline enum wme_ac ath11k_tid_to_ac(u32 tid) { return (((tid == 0) || (tid == 3)) ? WME_AC_BE : -@@ -325,6 +330,20 @@ struct ath11k_mgmt_frame_stats { +@@ -326,6 +331,20 @@ struct ath11k_mgmt_frame_stats { u32 tx_compl_fail[ATH11K_STATS_MGMT_FRM_TYPE_MAX]; }; @@ -69,9 +69,9 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_vif { u32 vdev_id; enum wmi_vdev_type vdev_type; -@@ -387,6 +406,11 @@ struct ath11k_vif { - struct ath11k_mgmt_frame_stats mgmt_stats; +@@ -390,6 +409,11 @@ struct ath11k_vif { struct arvif_nss nss; + #endif struct list_head ap_vlan_arvifs; + /* list required by Dynamic VLAN during fw_recovery */ + struct list_head dyn_vlan_cfg; @@ -83,7 +83,7 @@ Signed-off-by: Sathishkumar Muruganandam struct ath11k_vif_iter { --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -348,6 +348,10 @@ enum nl80211_he_gi ath11k_mac_he_gi_to_n +@@ -346,6 +346,10 @@ enum nl80211_he_gi ath11k_mac_he_gi_to_n return ret; } @@ -94,7 +94,7 @@ Signed-off-by: Sathishkumar Muruganandam u8 ath11k_mac_bw_to_mac80211_bw(u8 bw) { u8 ret = 0; -@@ -720,6 +724,33 @@ u8 ath11k_mac_get_target_pdev_id(struct +@@ -718,6 +722,33 @@ u8 ath11k_mac_get_target_pdev_id(struct return ar->ab->target_pdev_ids[0].pdev_id; } @@ -128,7 +128,7 @@ Signed-off-by: Sathishkumar Muruganandam static void ath11k_pdev_caps_update(struct ath11k *ar) { struct ath11k_base *ab = ar->ab; -@@ -4173,6 +4204,9 @@ static int ath11k_install_key(struct ath +@@ -4167,6 +4198,9 @@ static int ath11k_install_key(struct ath if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) return 0; @@ -138,7 +138,7 @@ Signed-off-by: Sathishkumar Muruganandam if (cmd == DISABLE_KEY) { arg.key_cipher = WMI_CIPHER_NONE; arg.key_data = NULL; -@@ -4262,15 +4296,40 @@ static int ath11k_clear_peer_keys(struct +@@ -4256,15 +4290,40 @@ static int ath11k_clear_peer_keys(struct return first_errno; } @@ -181,7 +181,7 @@ Signed-off-by: Sathishkumar Muruganandam const u8 *peer_addr; int ret = 0; u32 flags = 0; -@@ -4288,17 +4347,38 @@ static int ath11k_mac_op_set_key(struct +@@ -4282,17 +4341,38 @@ static int ath11k_mac_op_set_key(struct if (key->keyidx > WMI_MAX_KEY_INDEX) return -ENOSPC; @@ -224,7 +224,7 @@ Signed-off-by: Sathishkumar Muruganandam /* the peer should not disappear in mid-way (unless FW goes awry) since * we already hold conf_mutex. we just make sure its there now. */ -@@ -4343,6 +4423,74 @@ static int ath11k_mac_op_set_key(struct +@@ -4337,6 +4417,74 @@ static int ath11k_mac_op_set_key(struct goto exit; } @@ -299,7 +299,7 @@ Signed-off-by: Sathishkumar Muruganandam spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr); -@@ -4365,6 +4513,27 @@ static int ath11k_mac_op_set_key(struct +@@ -4359,6 +4507,27 @@ static int ath11k_mac_op_set_key(struct goto unlock; } @@ -327,7 +327,7 @@ Signed-off-by: Sathishkumar Muruganandam if (peer && cmd == SET_KEY) { peer->keys[key->keyidx] = key; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { -@@ -4374,18 +4543,23 @@ static int ath11k_mac_op_set_key(struct +@@ -4368,18 +4537,23 @@ static int ath11k_mac_op_set_key(struct peer->mcast_keyidx = key->keyidx; peer->sec_type_grp = ath11k_dp_tx_get_encrypt_type(key->cipher); } @@ -388,7 +388,7 @@ Signed-off-by: Sathishkumar Muruganandam static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, -@@ -5306,6 +5507,34 @@ static int ath11k_mac_op_sta_state(struc +@@ -5295,6 +5496,34 @@ static int ath11k_mac_op_sta_state(struc if (ret) ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n", sta->addr, arvif->vdev_id, ret); @@ -423,7 +423,7 @@ Signed-off-by: Sathishkumar Muruganandam } } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { -@@ -7045,7 +7274,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7013,7 +7242,7 @@ static int ath11k_mac_op_add_interface(s if ((vif->type == NL80211_IFTYPE_AP_VLAN || vif->type == NL80211_IFTYPE_STATION) && ab->nss.enabled) { if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET && @@ -432,7 +432,7 @@ Signed-off-by: Sathishkumar Muruganandam vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; arvif->nss.encap = ATH11K_HW_TXRX_ETHERNET; arvif->nss.decap = ATH11K_HW_TXRX_ETHERNET; -@@ -7058,6 +7287,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7026,6 +7255,7 @@ static int ath11k_mac_op_add_interface(s vif->addr, ret); goto err; } @@ -440,7 +440,7 @@ Signed-off-by: Sathishkumar Muruganandam mutex_unlock(&ar->conf_mutex); return ret; } -@@ -7082,6 +7312,20 @@ static int ath11k_mac_op_add_interface(s +@@ -7050,6 +7280,20 @@ static int ath11k_mac_op_add_interface(s arvif->vdev_id = bit; arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; @@ -461,7 +461,7 @@ Signed-off-by: Sathishkumar Muruganandam switch (vif->type) { case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_STATION: -@@ -7122,7 +7366,7 @@ static int ath11k_mac_op_add_interface(s +@@ -7090,7 +7334,7 @@ static int ath11k_mac_op_add_interface(s if (ret) { ath11k_warn(ab, "failed to create WMI vdev %d: %d\n", arvif->vdev_id, ret); @@ -470,7 +470,7 @@ Signed-off-by: Sathishkumar Muruganandam } ar->num_created_vdevs++; -@@ -7281,7 +7525,7 @@ err_peer_del: +@@ -7249,7 +7493,7 @@ err_peer_del: if (fbret) { ath11k_warn(ar->ab, "fallback fail to delete peer addr %pM vdev_id %d ret %d\n", vif->addr, arvif->vdev_id, fbret); @@ -479,7 +479,7 @@ Signed-off-by: Sathishkumar Muruganandam } } -@@ -7292,6 +7536,8 @@ err_vdev_del: +@@ -7260,6 +7504,8 @@ err_vdev_del: list_del(&arvif->list); spin_unlock_bh(&ar->data_lock); @@ -488,7 +488,7 @@ Signed-off-by: Sathishkumar Muruganandam err: mutex_unlock(&ar->conf_mutex); -@@ -7389,6 +7635,7 @@ err_vdev_del: +@@ -7357,6 +7603,7 @@ err_vdev_del: list_del(&arvif->list); spin_unlock_bh(&ar->data_lock); @@ -496,7 +496,7 @@ Signed-off-by: Sathishkumar Muruganandam ath11k_peer_cleanup(ar, arvif->vdev_id); idr_for_each(&ar->txmgmt_idr, -@@ -10113,8 +10360,11 @@ static int __ath11k_mac_register(struct +@@ -9956,8 +10203,11 @@ static int __ath11k_mac_register(struct ab->hw_params.bios_sar_capa) ar->hw->wiphy->sar_capa = ab->hw_params.bios_sar_capa; @@ -511,7 +511,7 @@ Signed-off-by: Sathishkumar Muruganandam if (ret) { --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -2001,6 +2001,7 @@ int ath11k_wmi_vdev_install_key(struct a +@@ -1938,6 +1938,7 @@ int ath11k_wmi_vdev_install_key(struct a cmd->key_len = arg->key_len; cmd->key_txmic_len = arg->key_txmic_len; cmd->key_rxmic_len = arg->key_rxmic_len; @@ -519,7 +519,7 @@ Signed-off-by: Sathishkumar Muruganandam if (arg->key_rsc_counter) memcpy(&cmd->key_rsc_counter, &arg->key_rsc_counter, -@@ -4275,6 +4276,7 @@ ath11k_wmi_copy_resource_config(struct w +@@ -4213,6 +4214,7 @@ ath11k_wmi_copy_resource_config(struct w wmi_cfg->flags2 = WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET; wmi_cfg->ema_max_vap_cnt = tg_cfg->ema_max_vap_cnt; wmi_cfg->ema_max_profile_period = tg_cfg->ema_max_profile_period; @@ -527,7 +527,7 @@ Signed-off-by: Sathishkumar Muruganandam } static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi, -@@ -4497,6 +4499,9 @@ int ath11k_wmi_cmd_init(struct ath11k_ba +@@ -4435,6 +4437,9 @@ int ath11k_wmi_cmd_init(struct ath11k_ba memset(&init_param, 0, sizeof(init_param)); memset(&config, 0, sizeof(config)); @@ -539,7 +539,7 @@ Signed-off-by: Sathishkumar Muruganandam if (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -3701,6 +3701,7 @@ struct wmi_vdev_install_key_arg { +@@ -3703,6 +3703,7 @@ struct wmi_vdev_install_key_arg { u32 vdev_id; const u8 *macaddr; u32 key_idx; @@ -547,7 +547,7 @@ Signed-off-by: Sathishkumar Muruganandam u32 key_flags; u32 key_cipher; u32 key_len; -@@ -5846,6 +5847,7 @@ struct target_resource_config { +@@ -5786,6 +5787,7 @@ struct target_resource_config { u32 bpf_instruction_size; u32 max_bssid_rx_filters; u32 use_pdev_id; diff --git a/package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch b/package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch new file mode 100644 index 0000000000..0362ff8caa --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/237-001-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -0,0 +1,101 @@ +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -1076,6 +1076,7 @@ struct ath11k_base { + u32 max_ast_index; + u32 num_ast_entries; + ++ bool stats_disable; + /* must be last */ + u8 drv_priv[] __aligned(sizeof(void *)); + }; +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -973,6 +973,79 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++static void ath11k_debug_config_mon_status(struct ath11k *ar, bool enable) ++{ ++ struct htt_rx_ring_tlv_filter tlv_filter = {0}; ++ struct ath11k_base *ab = ar->ab; ++ int i; ++ u32 ring_id; ++ ++ if (enable) ++ tlv_filter = ath11k_mac_mon_status_filter_default; ++ ++ for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { ++ ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; ++ ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ++ ar->dp.mac_id + i, ++ HAL_RXDMA_MONITOR_STATUS, ++ DP_RX_BUFFER_SIZE, ++ &tlv_filter); ++ } ++} ++ ++static ssize_t ath11k_write_stats_disable(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_base *ab = file->private_data; ++ struct ath11k_pdev *pdev; ++ bool disable; ++ int ret, i, radioup = 0; ++ u32 mask = 0; ++ ++ for (i = 0; i < ab->num_radios; i++) { ++ pdev = &ab->pdevs[i]; ++ if (pdev && pdev->ar) { ++ radioup = 1; ++ break; ++ } ++ } ++ ++ if (radioup == 0) { ++ ath11k_err(ab, "radio is not up\n"); ++ ret = -ENETDOWN; ++ goto exit; ++ } ++ ++ if (kstrtobool_from_user(user_buf, count, &disable)) ++ return -EINVAL; ++ ++ if (disable != ab->stats_disable) { ++ ab->stats_disable = disable; ++ for (i = 0; i < ab->num_radios; i++) { ++ pdev = &ab->pdevs[i]; ++ if (pdev && pdev->ar) { ++ ath11k_debug_config_mon_status(pdev->ar, !disable); ++ ++ if (!disable) ++ mask = HTT_PPDU_STATS_TAG_DEFAULT; ++ ++ ath11k_dp_tx_htt_h2t_ppdu_stats_req(pdev->ar, mask); ++ } ++ } ++ } ++ ++ ret = count; ++ ++exit: ++ return ret; ++} ++ ++static const struct file_operations fops_soc_stats_disable = { ++ .open = simple_open, ++ .write = ath11k_write_stats_disable, ++}; ++ + int ath11k_debugfs_pdev_create(struct ath11k_base *ab) + { + if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) +@@ -1022,6 +1095,8 @@ int ath11k_debugfs_soc_create(struct ath + ret = PTR_ERR(ab->debugfs_soc); + goto out; + } ++ debugfs_create_file("stats_disable", 0600, ab->debugfs_soc, ab, ++ &fops_soc_stats_disable); + + ret = 0; + diff --git a/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch b/package/kernel/mac80211/patches/nss/ath11k/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch similarity index 96% rename from package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch rename to package/kernel/mac80211/patches/nss/ath11k/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch index c054ee146f..db2bbfa0d2 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/237-003-ath11k-allocate-dst-ring-descriptors-from-cacheable-.patch @@ -24,7 +24,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -705,6 +705,7 @@ void ath11k_dp_tx_completion_handler(str +@@ -761,6 +761,7 @@ void ath11k_dp_tx_completion_handler(str struct sk_buff *msdu; struct hal_tx_status ts = { 0 }; struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id]; @@ -32,7 +32,7 @@ Signed-off-by: P Praneesh u32 *desc; u32 msdu_id; u8 mac_id; -@@ -713,9 +714,18 @@ void ath11k_dp_tx_completion_handler(str +@@ -769,9 +770,18 @@ void ath11k_dp_tx_completion_handler(str ath11k_hal_srng_access_begin(ab, status_ring); @@ -131,7 +131,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h -@@ -946,8 +946,12 @@ void ath11k_hal_srng_get_params(struct a +@@ -945,8 +945,12 @@ void ath11k_hal_srng_get_params(struct a u32 *ath11k_hal_srng_dst_get_next_entry(struct ath11k_base *ab, struct hal_srng *srng); u32 *ath11k_hal_srng_dst_peek(struct ath11k_base *ab, struct hal_srng *srng); diff --git a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch b/package/kernel/mac80211/patches/nss/ath11k/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch similarity index 70% rename from package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch rename to package/kernel/mac80211/patches/nss/ath11k/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch index 9bc2b50f7c..d25e43ec0b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/237-006-ath11k-Allow-fast-rx-by-bypassing-stats-update.patch @@ -23,7 +23,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -135,6 +135,7 @@ struct ath11k_skb_rxcb { +@@ -143,6 +143,7 @@ struct ath11k_skb_rxcb { u8 tid; u16 peer_id; u16 seq_no; @@ -31,109 +31,9 @@ Signed-off-by: P Praneesh }; enum ath11k_hw_rev { -@@ -1039,6 +1040,7 @@ struct ath11k_base { - struct ath11k_num_vdevs_peers *num_vdevs_peers; - - u32 rx_hash; -+ bool stats_disable; - - /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -1020,6 +1020,80 @@ static const struct file_operations fops - .open = simple_open, - .write = ath11k_write_rx_hash, - }; -+ -+static void ath11k_debug_config_mon_status(struct ath11k *ar, bool enable) -+{ -+ struct htt_rx_ring_tlv_filter tlv_filter = {0}; -+ struct ath11k_base *ab = ar->ab; -+ int i; -+ u32 ring_id; -+ -+ if (enable) -+ tlv_filter = ath11k_mac_mon_status_filter_default; -+ -+ for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { -+ ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; -+ ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, -+ ar->dp.mac_id + i, -+ HAL_RXDMA_MONITOR_STATUS, -+ DP_RX_BUFFER_SIZE, -+ &tlv_filter); -+ } -+} -+ -+static ssize_t ath11k_write_stats_disable(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k_base *ab = file->private_data; -+ struct ath11k_pdev *pdev; -+ bool disable; -+ int ret, i, radioup = 0; -+ u32 mask = 0; -+ -+ for (i = 0; i < ab->num_radios; i++) { -+ pdev = &ab->pdevs[i]; -+ if (pdev && pdev->ar) { -+ radioup = 1; -+ break; -+ } -+ } -+ -+ if (radioup == 0) { -+ ath11k_err(ab, "radio is not up\n"); -+ ret = -ENETDOWN; -+ goto exit; -+ } -+ -+ if (kstrtobool_from_user(user_buf, count, &disable)) -+ return -EINVAL; -+ -+ if (disable != ab->stats_disable) { -+ ab->stats_disable = disable; -+ for (i = 0; i < ab->num_radios; i++) { -+ pdev = &ab->pdevs[i]; -+ if (pdev && pdev->ar) { -+ ath11k_debug_config_mon_status(pdev->ar, !disable); -+ -+ if (!disable) -+ mask = HTT_PPDU_STATS_TAG_DEFAULT; -+ -+ ath11k_dp_tx_htt_h2t_ppdu_stats_req(pdev->ar, mask); -+ } -+ } -+ } -+ -+ ret = count; -+ -+exit: -+ return ret; -+} -+ -+static const struct file_operations fops_soc_stats_disable = { -+ .open = simple_open, -+ .write = ath11k_write_stats_disable, -+}; -+ - int ath11k_debugfs_pdev_create(struct ath11k_base *ab) - { - if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) -@@ -1035,7 +1109,7 @@ int ath11k_debugfs_pdev_create(struct at - debugfs_create_file("sram", 0400, ab->debugfs_soc, ab, - &fops_sram_dump); - -- debugfs_create_file("rx_hash", 0600, ab->debugfs_soc, ab, -+ debugfs_create_file("rx_hash", 0600, ab->debugfs_soc, ab, - &fops_soc_rx_hash); - - --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -375,6 +375,12 @@ static int ath11k_dp_purge_mon_ring(stru +@@ -340,6 +340,12 @@ static int ath11k_dp_purge_mon_ring(stru return -ETIMEDOUT; } @@ -146,7 +46,16 @@ Signed-off-by: P Praneesh /* Returns number of Rx buffers replenished */ int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id, struct dp_rxdma_ring *rx_ring, -@@ -2402,10 +2408,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b +@@ -1664,7 +1670,7 @@ int ath11k_dp_htt_tlv_iter(struct ath11k + len -= sizeof(*tlv); + + if (tlv_len > len) { +- ath11k_err(ab, "htt tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n", ++ ath11k_err(ab, "htt tlv parse failure of tag %hu at byte %zd (%zu bytes left, %hu expected)\n", + tlv_tag, ptr - begin, len, tlv_len); + return -EINVAL; + } +@@ -2454,10 +2460,60 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; } @@ -208,17 +117,22 @@ Signed-off-by: P Praneesh { bool fill_crypto_hdr; enum hal_encrypt_type enctype; -@@ -2417,6 +2473,9 @@ static void ath11k_dp_rx_h_mpdu(struct a +@@ -2468,9 +2524,13 @@ static void ath11k_dp_rx_h_mpdu(struct a + struct rx_attention *rx_attention; u32 err_bitmap; - + struct wireless_dev *wdev = NULL; + struct ath11k_sta *arsta = NULL; + /* PN for multicast packets will be checked in mac80211 */ rxcb = ATH11K_SKB_RXCB(msdu); - fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); -@@ -2430,6 +2489,30 @@ static void ath11k_dp_rx_h_mpdu(struct a +- fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); ++ if (!ar->ab->nss.enabled) ++ fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); + rxcb->is_mcbc = fill_crypto_hdr; + + if (rxcb->is_mcbc) { +@@ -2481,6 +2541,26 @@ static void ath11k_dp_rx_h_mpdu(struct a spin_lock_bh(&ar->ab->base_lock); peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu); if (peer) { @@ -238,18 +152,23 @@ Signed-off-by: P Praneesh + if (peer->sta) + arsta = + (struct ath11k_sta *)peer->sta->drv_priv; -+ if (arsta) -+ atomic_inc(&arsta->drv_rx_pkts.pkts_out_to_netif); + return; + } + } -+ -+ *fast_rx = false; + if (rxcb->is_mcbc) enctype = peer->sec_type_grp; else -@@ -2693,7 +2776,8 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -2490,6 +2570,8 @@ static void ath11k_dp_rx_h_mpdu(struct a + } + spin_unlock_bh(&ar->ab->base_lock); + ++ *fast_rx = false; ++ + rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc); + err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention); + if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) +@@ -2731,7 +2813,8 @@ static void ath11k_dp_rx_deliver_msdu(st static int ath11k_dp_rx_process_msdu(struct ath11k *ar, struct sk_buff *msdu, struct sk_buff_head *msdu_list, @@ -259,7 +178,7 @@ Signed-off-by: P Praneesh { struct ath11k_base *ab = ar->ab; struct hal_rx_desc *rx_desc, *lrx_desc; -@@ -2775,8 +2859,13 @@ static int ath11k_dp_rx_process_msdu(str +@@ -2798,8 +2881,13 @@ static int ath11k_dp_rx_process_msdu(str } } @@ -274,7 +193,7 @@ Signed-off-by: P Praneesh rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -@@ -2791,10 +2880,12 @@ static void ath11k_dp_rx_process_receive +@@ -2814,10 +2902,12 @@ static void ath11k_dp_rx_process_receive struct sk_buff_head *msdu_list, int mac_id) { @@ -287,7 +206,7 @@ Signed-off-by: P Praneesh if (skb_queue_empty(msdu_list)) return; -@@ -2811,7 +2902,12 @@ static void ath11k_dp_rx_process_receive +@@ -2834,7 +2924,12 @@ static void ath11k_dp_rx_process_receive } while ((msdu = __skb_dequeue(msdu_list))) { @@ -301,7 +220,7 @@ Signed-off-by: P Praneesh if (unlikely(ret)) { ath11k_dbg(ab, ATH11K_DBG_DATA, "Unable to process msdu %d", ret); -@@ -2819,7 +2915,10 @@ static void ath11k_dp_rx_process_receive +@@ -2842,7 +2937,10 @@ static void ath11k_dp_rx_process_receive continue; } @@ -313,15 +232,29 @@ Signed-off-by: P Praneesh } } -@@ -4117,6 +4216,7 @@ static int ath11k_dp_rx_h_null_q_desc(st - struct ath11k_sta *arsta = NULL; - u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; - u32 peer_id; +@@ -2851,11 +2949,12 @@ void ath11k_dp_rx_from_nss(struct ath11k + { + struct ieee80211_rx_status rx_status = {0}; + struct ath11k_skb_rxcb *rxcb; ++ bool fast_rx = false; + + rxcb = ATH11K_SKB_RXCB(msdu); + + ath11k_dp_rx_h_ppdu(ar, rxcb->rx_desc, &rx_status); +- ath11k_dp_rx_h_mpdu(ar, msdu, rxcb->rx_desc, &rx_status); ++ ath11k_dp_rx_h_mpdu(ar, msdu, rxcb->rx_desc, &rx_status, &fast_rx); + + rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; + +@@ -4322,6 +4421,7 @@ static int ath11k_dp_rx_h_null_q_desc(st + struct ieee80211_rx_status *status, + struct sk_buff_head *msdu_list) + { + bool fast_rx; - - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc); - -@@ -4160,7 +4260,8 @@ static int ath11k_dp_rx_h_null_q_desc(st + u16 msdu_len; + struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + struct rx_attention *rx_attention; +@@ -4371,7 +4471,8 @@ static int ath11k_dp_rx_h_null_q_desc(st } ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -333,7 +266,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -303,6 +303,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge +@@ -293,6 +293,16 @@ static bool ath11k_hw_ipq8074_rx_desc_ge __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); } @@ -350,7 +283,7 @@ Signed-off-by: P Praneesh static bool ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) { return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_CTRL_VALID, -@@ -590,6 +600,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge +@@ -470,6 +480,16 @@ static bool ath11k_hw_qcn9074_rx_desc_ge __le32_to_cpu(desc->u.qcn9074.msdu_start.info2)); } @@ -367,7 +300,7 @@ Signed-off-by: P Praneesh static bool ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc) { return !!FIELD_GET(RX_MPDU_START_INFO11_MPDU_SEQ_CTRL_VALID, -@@ -1132,6 +1152,7 @@ const struct ath11k_hw_ops qca6390_ops = +@@ -1025,6 +1045,7 @@ const struct ath11k_hw_ops qca6390_ops = .rx_desc_get_encrypt_type = ath11k_hw_ipq8074_rx_desc_get_encrypt_type, .rx_desc_get_decap_type = ath11k_hw_ipq8074_rx_desc_get_decap_type, .rx_desc_get_mesh_ctl = ath11k_hw_ipq8074_rx_desc_get_mesh_ctl, @@ -375,7 +308,7 @@ Signed-off-by: P Praneesh .rx_desc_get_ldpc_support = ath11k_hw_ipq8074_rx_desc_get_ldpc_support, .rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld, .rx_desc_get_mpdu_fc_valid = ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid, -@@ -1293,6 +1314,7 @@ const struct ath11k_hw_ops ipq5018_ops = +@@ -1189,6 +1210,7 @@ const struct ath11k_hw_ops ipq5018_ops = .rx_desc_get_encrypt_type = ath11k_hw_qcn9074_rx_desc_get_encrypt_type, .rx_desc_get_decap_type = ath11k_hw_qcn9074_rx_desc_get_decap_type, .rx_desc_get_mesh_ctl = ath11k_hw_qcn9074_rx_desc_get_mesh_ctl, @@ -385,7 +318,7 @@ Signed-off-by: P Praneesh .rx_desc_get_mpdu_fc_valid = ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid, --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -287,6 +287,7 @@ struct ath11k_hw_ops { +@@ -260,6 +260,7 @@ struct ath11k_hw_ops { u32 (*rx_desc_get_encrypt_type)(struct hal_rx_desc *desc); u8 (*rx_desc_get_decap_type)(struct hal_rx_desc *desc); u8 (*rx_desc_get_mesh_ctl)(struct hal_rx_desc *desc); @@ -395,7 +328,7 @@ Signed-off-by: P Praneesh bool (*rx_desc_get_mpdu_fc_valid)(struct hal_rx_desc *desc); --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -5201,6 +5201,14 @@ static int ath11k_mac_op_sta_state(struc +@@ -5527,6 +5527,14 @@ static int ath11k_mac_op_sta_state(struc } } else if (old_state == IEEE80211_STA_AUTHORIZED && new_state == IEEE80211_STA_ASSOC) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch similarity index 87% rename from package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch rename to package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch index 79906c8d3a..c4042611d3 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-244-ath11k-dp-tx-perf.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/244-ath11k-dp-tx-perf.patch @@ -26,7 +26,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -118,6 +118,7 @@ static inline enum wme_ac ath11k_tid_to_ +@@ -115,6 +115,7 @@ static inline enum wme_ac ath11k_tid_to_ enum ath11k_skb_flags { ATH11K_SKB_HW_80211_ENCAP = BIT(0), ATH11K_SKB_CIPHER_SET = BIT(1), @@ -34,22 +34,23 @@ Signed-off-by: P Praneesh }; struct ath11k_skb_cb { -@@ -919,7 +920,12 @@ struct ath11k_soc_dp_tx_err_stats { +@@ -883,10 +884,13 @@ struct ath11k_dp_ring_bp_stats { + struct ath11k_soc_dp_tx_err_stats { + /* TCL Ring Descriptor unavailable */ + u32 desc_na[DP_TCL_NUM_RING_MAX]; ++ /* TCL Ring IDR unavailable */ ++ u32 idr_na[DP_TCL_NUM_RING_MAX]; /* Other failures during dp_tx due to mem allocation failure * idr unavailable etc. */ -+ /* TCL Ring IDR unavailable */ -+ u32 idr_na[DP_TCL_NUM_RING_MAX]; -+ atomic_t misc_fail; + atomic_t max_fail; -+ /* Tx failures due to NSS Tx error status */ + /* Tx failures due to NSS Tx error status */ atomic_t nss_tx_fail; }; - --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -362,7 +362,7 @@ void ath11k_dp_stop_shadow_timers(struct +@@ -358,7 +358,7 @@ void ath11k_dp_stop_shadow_timers(struct if (!ab->hw_params.supports_shadow_regs) return; @@ -58,7 +59,7 @@ Signed-off-by: P Praneesh ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]); ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer); -@@ -377,7 +377,7 @@ static void ath11k_dp_srng_common_cleanu +@@ -373,7 +373,7 @@ static void ath11k_dp_srng_common_cleanu ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring); ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring); ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring); @@ -67,7 +68,7 @@ Signed-off-by: P Praneesh ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring); ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring); } -@@ -411,6 +411,11 @@ static int ath11k_dp_srng_common_setup(s +@@ -407,6 +407,11 @@ static int ath11k_dp_srng_common_setup(s goto err; } @@ -79,7 +80,7 @@ Signed-off-by: P Praneesh ret = ath11k_dp_srng_setup(ab, &dp->tcl_status_ring, HAL_TCL_STATUS, 0, 0, DP_TCL_STATUS_RING_SIZE); if (ret) { -@@ -418,7 +423,7 @@ static int ath11k_dp_srng_common_setup(s +@@ -414,7 +419,7 @@ static int ath11k_dp_srng_common_setup(s goto err; } @@ -88,7 +89,7 @@ Signed-off-by: P Praneesh tcl_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].tcl_ring_num; wbm_num = ab->hw_params.hal_params->tcl2wbm_rbm_map[i].wbm_ring_num; -@@ -441,7 +446,7 @@ static int ath11k_dp_srng_common_setup(s +@@ -437,7 +442,7 @@ static int ath11k_dp_srng_common_setup(s } srng = &ab->hal.srng_list[dp->tx_ring[i].tcl_data_ring.ring_id]; @@ -97,7 +98,7 @@ Signed-off-by: P Praneesh ath11k_dp_shadow_init_timer(ab, &dp->tx_ring_timer[i], ATH11K_SHADOW_DP_TIMER_INTERVAL, -@@ -1062,7 +1067,7 @@ void ath11k_dp_free(struct ath11k_base * +@@ -1051,7 +1056,7 @@ void ath11k_dp_free(struct ath11k_base * ath11k_dp_reo_cmd_list_cleanup(ab); @@ -106,7 +107,7 @@ Signed-off-by: P Praneesh spin_lock_bh(&dp->tx_ring[i].tx_idr_lock); idr_for_each(&dp->tx_ring[i].txbuf_idr, ath11k_dp_tx_pending_cleanup, ab); -@@ -1114,7 +1119,7 @@ int ath11k_dp_alloc(struct ath11k_base * +@@ -1102,7 +1107,7 @@ int ath11k_dp_alloc(struct ath11k_base * size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; @@ -117,7 +118,7 @@ Signed-off-by: P Praneesh dp->tx_ring[i].tcl_data_ring_id = i; --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -121,27 +121,35 @@ int ath11k_dp_tx(struct ath11k *ar, stru +@@ -134,28 +134,34 @@ int ath11k_dp_tx(struct ath11k *ar, stru u32 ring_selector = 0; u8 ring_map = 0; bool tcl_ring_retry, is_diff_encap = false; @@ -131,9 +132,10 @@ Signed-off-by: P Praneesh !ieee80211_is_data(hdr->frame_control))) return -ENOTSUPP; -- ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb); +- pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1); + max_tx_ring = ab->hw_params.max_tx_ring; -+ + +- ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb); +#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + if (unlikely(atomic_read(&ab->num_max_allowed) > DP_TX_COMP_MAX_ALLOWED)) { + atomic_inc(&ab->soc_stats.tx_err.max_fail); @@ -141,7 +143,7 @@ Signed-off-by: P Praneesh + } +#endif + ring_selector = smp_processor_id();; - pool_id = ring_selector; ++ pool_id = ring_selector; tcl_ring_sel: tcl_ring_retry = false; @@ -153,16 +155,15 @@ Signed-off-by: P Praneesh + DP_TCL_NUM_RING_MAX - 1 : ring_id; - ring_map |= BIT(ti.ring_id); ++ ring_map |= BIT(ring_id); - tx_ring = &dp->tx_ring[ti.ring_id]; -+ ring_map |= BIT(ring_id); -+ + ti.buf_id = tcl_ring_id + HAL_RX_BUF_RBM_SW0_BM; + tx_ring = &dp->tx_ring[tcl_ring_id]; spin_lock_bh(&tx_ring->tx_idr_lock); ret = idr_alloc(&tx_ring->txbuf_idr, skb, 0, -@@ -149,9 +157,9 @@ tcl_ring_sel: +@@ -163,9 +169,9 @@ tcl_ring_sel: spin_unlock_bh(&tx_ring->tx_idr_lock); if (unlikely(ret < 0)) { @@ -174,7 +175,7 @@ Signed-off-by: P Praneesh return -ENOSPC; } -@@ -260,6 +268,11 @@ tcl_ring_sel: +@@ -276,6 +282,11 @@ tcl_ring_sel: ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN; } @@ -186,7 +187,7 @@ Signed-off-by: P Praneesh ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(ab->dev, ti.paddr))) { atomic_inc(&ab->soc_stats.tx_err.misc_fail); -@@ -268,13 +281,13 @@ tcl_ring_sel: +@@ -284,13 +295,13 @@ tcl_ring_sel: goto fail_remove_idr; } @@ -205,7 +206,7 @@ Signed-off-by: P Praneesh tcl_ring = &ab->hal.srng_list[hal_ring_id]; spin_lock_bh(&tcl_ring->lock); -@@ -287,7 +300,7 @@ tcl_ring_sel: +@@ -303,7 +314,7 @@ tcl_ring_sel: * desc because the desc is directly enqueued onto hw queue. */ ath11k_hal_srng_access_end(ab, tcl_ring); @@ -214,7 +215,7 @@ Signed-off-by: P Praneesh spin_unlock_bh(&tcl_ring->lock); ret = -ENOMEM; -@@ -296,8 +309,8 @@ tcl_ring_sel: +@@ -312,8 +323,8 @@ tcl_ring_sel: * checking this ring earlier for each pkt tx. * Restart ring selection if some rings are not checked yet. */ @@ -225,7 +226,7 @@ Signed-off-by: P Praneesh tcl_ring_retry = true; ring_selector++; } -@@ -308,17 +321,17 @@ tcl_ring_sel: +@@ -324,17 +335,17 @@ tcl_ring_sel: ath11k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc + sizeof(struct hal_tlv_hdr), &ti); @@ -246,7 +247,7 @@ Signed-off-by: P Praneesh return 0; -@@ -365,7 +378,6 @@ static void ath11k_dp_tx_free_txbuf(stru +@@ -381,7 +392,6 @@ static void ath11k_dp_tx_free_txbuf(stru ar = ab->pdevs[mac_id].ar; if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); @@ -254,7 +255,7 @@ Signed-off-by: P Praneesh } static void -@@ -379,6 +391,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct +@@ -395,6 +405,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct struct ath11k_skb_cb *skb_cb; struct ath11k *ar; struct ath11k_peer *peer; @@ -262,7 +263,7 @@ Signed-off-by: P Praneesh spin_lock(&tx_ring->tx_idr_lock); msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); -@@ -397,10 +410,30 @@ ath11k_dp_tx_htt_tx_complete_buf(struct +@@ -413,10 +424,30 @@ ath11k_dp_tx_htt_tx_complete_buf(struct if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); @@ -294,7 +295,7 @@ Signed-off-by: P Praneesh if (!skb_cb->vif) { ieee80211_free_txskb(ar->hw, msdu); return; -@@ -616,6 +649,7 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -632,6 +663,7 @@ static void ath11k_dp_tx_complete_msdu(s struct ath11k_peer *peer; struct ath11k_sta *arsta; struct rate_info rate; @@ -302,7 +303,7 @@ Signed-off-by: P Praneesh if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) { /* Must not happen */ -@@ -626,6 +660,20 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -642,6 +674,20 @@ static void ath11k_dp_tx_complete_msdu(s dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); @@ -323,7 +324,7 @@ Signed-off-by: P Praneesh if (unlikely(!rcu_access_pointer(ab->pdevs_active[ar->pdev_idx]))) { ieee80211_free_txskb(ar->hw, msdu); return; -@@ -680,7 +728,7 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -696,7 +742,7 @@ static void ath11k_dp_tx_complete_msdu(s spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find_by_id(ab, ts->peer_id); @@ -332,7 +333,7 @@ Signed-off-by: P Praneesh ath11k_dbg(ab, ATH11K_DBG_DATA, "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); -@@ -736,19 +784,36 @@ static inline void ath11k_dp_tx_status_p +@@ -752,19 +798,36 @@ static inline void ath11k_dp_tx_status_p ts->rate_stats = 0; } @@ -342,7 +343,7 @@ Signed-off-by: P Praneesh + + if (FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0) == + HAL_WBM_REL_SRC_MODULE_FW) { -+ status_desc = ((u8 *)desc) + HTT_TX_WBM_COMP_STATUS_OFFSET; ++ status_desc = ((struct htt_tx_wbm_completion *)desc) + HTT_TX_WBM_COMP_STATUS_OFFSET; + + /* Dont consider HTT_TX_COMP_STATUS_MEC_NOTIFY */ + if (FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS, status_desc->info0) == @@ -371,7 +372,7 @@ Signed-off-by: P Praneesh spin_lock_bh(&status_ring->lock); -@@ -763,33 +828,27 @@ void ath11k_dp_tx_completion_handler(str +@@ -779,33 +842,27 @@ void ath11k_dp_tx_completion_handler(str ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries); @@ -384,7 +385,7 @@ Signed-off-by: P Praneesh - ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head); - } + while ((desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) { -+ if (!ath11k_dp_tx_completion_valid(desc)) ++ if (!ath11k_dp_tx_completion_valid((struct hal_wbm_release_ring *)desc)) + continue; - if (unlikely((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) && @@ -419,7 +420,7 @@ Signed-off-by: P Praneesh ath11k_dp_tx_status_parse(ab, tx_status, &ts); desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, -@@ -822,7 +881,6 @@ void ath11k_dp_tx_completion_handler(str +@@ -838,7 +895,6 @@ void ath11k_dp_tx_completion_handler(str wake_up(&ar->dp.tx_empty_waitq); ath11k_dp_tx_complete_msdu(ar, msdu, &ts); @@ -429,7 +430,7 @@ Signed-off-by: P Praneesh --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -6723,12 +6723,22 @@ static void ath11k_mac_op_tx(struct ieee +@@ -6664,12 +6664,22 @@ static void ath11k_mac_op_tx(struct ieee if (control->sta) arsta = ath11k_sta_to_arsta(control->sta); @@ -453,7 +454,7 @@ Signed-off-by: P Praneesh ieee80211_free_txskb(ar->hw, skb); return; } -@@ -7690,7 +7700,7 @@ err_vdev_del: +@@ -7617,7 +7627,7 @@ err_vdev_del: idr_for_each(&ar->txmgmt_idr, ath11k_mac_vif_txmgmt_idr_remove, vif); @@ -464,7 +465,7 @@ Signed-off-by: P Praneesh ath11k_mac_vif_unref, vif); --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -833,10 +833,22 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -832,10 +832,22 @@ static ssize_t ath11k_debugfs_dump_soc_d len += scnprintf(buf + len, size - len, "ring%d: %u\n", i, soc_stats->tx_err.desc_na[i]); @@ -489,7 +490,7 @@ Signed-off-by: P Praneesh if (len > size) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -192,7 +192,6 @@ static struct ath11k_hw_params ath11k_hw +@@ -188,7 +188,6 @@ static struct ath11k_hw_params ath11k_hw .supports_regdb = false, .fix_l1ss = true, .credit_flow = false, @@ -497,7 +498,7 @@ Signed-off-by: P Praneesh .hal_params = &ath11k_hw_hal_params_ipq8074, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = true, -@@ -217,6 +216,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -213,6 +212,8 @@ static struct ath11k_hw_params ath11k_hw .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, .support_fw_mac_sequence = false, @@ -506,7 +507,15 @@ Signed-off-by: P Praneesh }, { .name = "qca6390 hw2.0", -@@ -384,6 +384,8 @@ static struct ath11k_hw_params ath11k_hw +@@ -355,7 +356,6 @@ static struct ath11k_hw_params ath11k_hw + .supports_regdb = false, + .fix_l1ss = true, + .credit_flow = false, +- .max_tx_ring = DP_TCL_NUM_RING_MAX, + .hal_params = &ath11k_hw_hal_params_ipq8074, + .supports_dynamic_smps_6ghz = true, + .alloc_cacheable_memory = true, +@@ -380,6 +380,8 @@ static struct ath11k_hw_params ath11k_hw .tx_ring_size = DP_TCL_DATA_RING_SIZE, .smp2p_wow_exit = false, .support_fw_mac_sequence = false, @@ -515,9 +524,9 @@ Signed-off-by: P Praneesh }, { .name = "wcn6855 hw2.0", -@@ -2147,6 +2149,9 @@ int ath11k_core_pre_init(struct ath11k_b - - ab->enable_memory_stats = ATH11K_DEBUG_ENABLE_MEMORY_STATS; +@@ -2143,6 +2145,9 @@ int ath11k_core_pre_init(struct ath11k_b + if (nss_offload) + ab->nss.stats_enabled = 1; + if (ab->nss.enabled && ab->hw_params.max_tx_ring > DP_TCL_NUM_RING_MAX) + ab->hw_params.max_tx_ring = DP_TCL_NUM_RING_MAX; @@ -570,7 +579,7 @@ Signed-off-by: P Praneesh FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_DESC_TYPE, ti->type) | FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE, ti->encap_type) | FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCRYPT_TYPE, -@@ -60,23 +60,25 @@ void ath11k_hal_tx_cmd_desc_setup(struct +@@ -60,24 +60,26 @@ void ath11k_hal_tx_cmd_desc_setup(struct FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, ti->meta_data_flags); @@ -581,6 +590,7 @@ Signed-off-by: P Praneesh - tcl_cmd->info2 = ti->flags1 | + tcl_cmd.info2 = ti->flags1 | + FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID, ti->tid) | FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ti->lmac_id); - tcl_cmd->info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX, @@ -601,7 +611,7 @@ Signed-off-by: P Praneesh } void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id) -@@ -136,7 +138,9 @@ void ath11k_hal_tx_set_dscp_tid_map(stru +@@ -137,7 +139,9 @@ void ath11k_hal_tx_set_dscp_tid_map(stru ctrl_reg_val); } @@ -612,7 +622,7 @@ Signed-off-by: P Praneesh { struct hal_srng_params params; struct hal_tlv_hdr *tlv; -@@ -145,7 +149,7 @@ void ath11k_hal_tx_init_data_ring(struct +@@ -146,7 +150,7 @@ void ath11k_hal_tx_init_data_ring(struct memset(¶ms, 0, sizeof(params)); diff --git a/package/kernel/mac80211/patches/nss/ath11k/300-ath11k-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/ath11k/300-ath11k-nss-mesh-offload-support.patch new file mode 100644 index 0000000000..30848b8f61 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/300-ath11k-nss-mesh-offload-support.patch @@ -0,0 +1,3365 @@ +From fbe5a76d8c9ff1cf3f906a3c863928fc1adcbc95 Mon Sep 17 00:00:00 2001 +From: Karthikeyan Kathirvel +Date: Tue, 16 Feb 2021 13:44:39 +0530 +Subject: [PATCH] ath11k: Add mesh nss offload support + +- New capability advertising nss offload support for mesh type +- Mesh obj vap and link vap registration/clean up +- Command/event handling +- New .ch files in ath11k for nss mesh offload related debugs +- Tx/Rx data path on mesh link vap uses native wifi format +- Mesh obj vap handls packets in ether format. No Tx on Mesh + obj vap is expected as packets transmitted in slow path is + supposed to be encapsulated in 802.11 format. +- New mac80211-driver callbacks for mesh vap, mpath and mpp + configurations. + +Signed-off-by: Vasanthakumar Thiagarajan + +Change-Id: Ib6950344286ba18fab43586262c62dcd09557614 +Co-developed-by: Karthikeyan Kathirvel +Signed-off-by: Karthikeyan Kathirvel +Signed-off-by: Vasanthakumar Thiagarajan +--- + drivers/net/wireless/ath/ath11k/Makefile | 2 +- + drivers/net/wireless/ath/ath11k/debug_nss.c | 343 +++++++ + drivers/net/wireless/ath/ath11k/debug_nss.h | 24 + + drivers/net/wireless/ath/ath11k/dp.h | 16 +- + drivers/net/wireless/ath/ath11k/dp_rx.c | 170 ++- + drivers/net/wireless/ath/ath11k/dp_rx.h | 2 + + drivers/net/wireless/ath/ath11k/mac.c | 36 +- + drivers/net/wireless/ath/ath11k/nss.c | 1482 ++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath11k/nss.h | 63 +- + 19 files changed, 2548 insertions(+), 206 deletions(-) + create mode 100644 drivers/net/wireless/ath/ath11k/debug_nss.c + create mode 100644 drivers/net/wireless/ath/ath11k/debug_nss.h + +--- a/drivers/net/wireless/ath/ath11k/Makefile ++++ b/drivers/net/wireless/ath/ath11k/Makefile +@@ -27,6 +27,10 @@ ath11k-$(CPTCFG_ATH11K_SPECTRAL) += spec + ath11k-$(CONFIG_PM) += wow.o + ath11k-$(CPTCFG_ATH11K_NSS_SUPPORT) += nss.o + ++ifeq ($(and $(CPTCFG_ATH11K_DEBUGFS),$(CPTCFG_ATH11K_NSS_MESH_SUPPORT)),y) ++ath11k-y += debug_nss.o ++endif ++ + obj-$(CPTCFG_ATH11K_AHB) += ath11k_ahb.o + ath11k_ahb-y += ahb.o + +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/debug_nss.c +@@ -0,0 +1,924 @@ ++// SPDX-License-Identifier: BSD-3-Clause-Clear ++/* ++ * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#ifdef CPTCFG_ATH11K_NSS_SUPPORT ++ ++#include ++#include "dp_rx.h" ++#include "nss.h" ++#include "debug.h" ++#include "debug_nss.h" ++ ++static unsigned int ++debug_nss_fill_mpp_dump(struct ath11k_vif *arvif, char *buf, ssize_t size) ++{ ++ struct arvif_nss *nss = &arvif->nss; ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_nss_mpp_entry *entry, *tmp; ++ LIST_HEAD(local_entry); ++ unsigned int len = 0; ++ int i; ++ ++ len += scnprintf(buf + len, size - len, "\nProxy path table\n"); ++ len += scnprintf(buf + len, size - len, "dest_mac_addr\t\tmesh_dest_mac\t\tflags\n"); ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&nss->mpp_dump, &local_entry); ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(entry, tmp, &local_entry, list) { ++ for (i = 0; i < entry->num_entries; i++) ++ len += scnprintf(buf + len, size - len, "%pM\t%pM\t0x%x\n", ++ entry->mpp[i].dest_mac_addr, ++ entry->mpp[i].mesh_dest_mac, entry->mpp[i].flags); ++ list_del(&entry->list); ++ kfree(entry); ++ } ++ ++ return len; ++} ++ ++static int ath11k_nss_dump_mpp_open(struct inode *inode, struct file *file) ++{ ++ struct ath11k_vif *arvif = inode->i_private; ++ struct ath11k *ar = arvif->ar; ++ unsigned long time_left; ++ struct ath11k_nss_dbg_priv_data *priv_data; ++ int ret; ++ ssize_t size = 100; ++ char *buf; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ reinit_completion(&arvif->nss.dump_mpp_complete); ++ ++ priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); ++ if (!priv_data) { ++ mutex_unlock(&ar->conf_mutex); ++ return -ENOMEM; ++ } ++ ++ priv_data->arvif = arvif; ++ ret = ath11k_nss_dump_mpp_request(arvif); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send dump mpp command %d\n", ret); ++ goto err_unlock; ++ } ++ ++ time_left = wait_for_completion_timeout(&arvif->nss.dump_mpp_complete, ++ ATH11K_NSS_MPATH_DUMP_TIMEOUT); ++ if (time_left == 0) { ++ ret = -ETIMEDOUT; ++ goto err_unlock; ++ } ++ ++ mutex_unlock(&ar->conf_mutex); ++ ++ size += (arvif->nss.mpp_dump_num_entries * 200 + 10 * 100); ++ buf = kmalloc(size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ priv_data->buf = buf; ++ ++ priv_data->len= debug_nss_fill_mpp_dump(arvif, buf, size); ++ ++ file->private_data = priv_data; ++ ++ return 0; ++ ++err_unlock: ++ kfree(priv_data); ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static int ath11k_nss_dump_mpp_release(struct inode *inode, struct file *file) ++{ ++ struct ath11k_nss_dbg_priv_data *priv_data = file->private_data; ++ ++ kfree(priv_data->buf); ++ kfree(priv_data); ++ return 0; ++} ++ ++static ssize_t ath11k_nss_dump_mpp_read(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_nss_dbg_priv_data *priv_data = file->private_data; ++ struct ath11k_vif *arvif = priv_data->arvif; ++ char *buf = priv_data->buf; ++ struct ath11k *ar = arvif->ar; ++ int ret; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, priv_data->len); ++ ++ mutex_unlock(&ar->conf_mutex); ++ ++ return ret; ++} ++ ++static const struct file_operations fops_nss_dump_mpp_table = { ++ .open = ath11k_nss_dump_mpp_open, ++ .read = ath11k_nss_dump_mpp_read, ++ .release = ath11k_nss_dump_mpp_release, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static unsigned int ++debug_nss_fill_mpath_dump(struct ath11k_vif *arvif, char *buf, ssize_t size) ++{ ++ struct arvif_nss *nss = &arvif->nss; ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_nss_mpath_entry *entry, *tmp; ++ LIST_HEAD(local_entry); ++ unsigned int len = 0; ++ u64 expiry_time; ++ int i; ++ ++ len += scnprintf(buf + len, size - len, "\nmpath table\n"); ++ len += scnprintf(buf + len, size - len, "dest_mac_addr\t\tnext_hop_mac\t\tmetric\t" ++ "expiry_time\thop_count\tflags\tlink_vap_id\n"); ++ ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&nss->mpath_dump, &local_entry); ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(entry, tmp, &local_entry, list) { ++ for (i = 0; i < entry->num_entries; i++) { ++ memcpy(&expiry_time, entry->mpath[i].expiry_time, sizeof(u64)); ++ len += scnprintf(buf + len, size - len, "%pM\t%pM\t%u\t%llu\t\t\t%d\t0x%x\t%d\n", ++ entry->mpath[i].dest_mac_addr, ++ entry->mpath[i].next_hop_mac_addr, entry->mpath[i].metric, ++ expiry_time, entry->mpath[i].hop_count, ++ entry->mpath[i].flags, entry->mpath[i].link_vap_id); ++ } ++ kfree(entry); ++ } ++ ++ return len; ++} ++ ++static int ath11k_nss_dump_mpath_open(struct inode *inode, struct file *file) ++{ ++ struct ath11k_vif *arvif = inode->i_private; ++ struct ath11k *ar = arvif->ar; ++ unsigned long time_left; ++ struct ath11k_nss_dbg_priv_data *priv_data; ++ ssize_t size = 200; ++ char *buf; ++ int ret; ++ ++ reinit_completion(&arvif->nss.dump_mpath_complete); ++ ++ priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); ++ if (!priv_data) ++ return -ENOMEM; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ priv_data->arvif = arvif; ++ ret = ath11k_nss_dump_mpath_request(arvif); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to send dump mpath command %d\n", ret); ++ goto err_unlock; ++ } ++ ++ time_left = wait_for_completion_timeout(&arvif->nss.dump_mpath_complete, ++ ATH11K_NSS_MPATH_DUMP_TIMEOUT); ++ if (time_left == 0) { ++ ret = -ETIMEDOUT; ++ goto err_unlock; ++ } ++ ++ mutex_unlock(&ar->conf_mutex); ++ ++ size += (arvif->nss.mpath_dump_num_entries * 200 + 10 * 100); ++ buf = kmalloc(size, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ priv_data->buf = buf; ++ ++ priv_data->len = debug_nss_fill_mpath_dump(arvif, buf, size); ++ ++ file->private_data = priv_data; ++ ++ return 0; ++ ++err_unlock: ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ ++static int ath11k_nss_dump_mpath_release(struct inode *inode, struct file *file) ++{ ++ struct ath11k_nss_dbg_priv_data *priv_data = file->private_data; ++ ++ kfree(priv_data->buf); ++ kfree(priv_data); ++ return 0; ++ ++} ++ ++static ssize_t ath11k_nss_dump_mpath_read(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_nss_dbg_priv_data *priv_data = file->private_data; ++ struct ath11k_vif *arvif = priv_data->arvif; ++ char *buf = priv_data->buf; ++ struct ath11k *ar = arvif->ar; ++ int ret; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, priv_data->len); ++ ++ mutex_unlock(&ar->conf_mutex); ++ ++ return ret; ++} ++ ++static const struct file_operations fops_nss_dump_mpath_table = { ++ .open = ath11k_nss_dump_mpath_open, ++ .read = ath11k_nss_dump_mpath_read, ++ .release = ath11k_nss_dump_mpath_release, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_mpath_add(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ieee80211_mesh_path_offld path = {0}; ++ u8 buf[128] = {0}; ++ int ret; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%u %hhu %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %hhu %hhu", ++ &path.metric, ++ &path.hop_count, ++ &path.mesh_da[0], ++ &path.mesh_da[1], ++ &path.mesh_da[2], ++ &path.mesh_da[3], ++ &path.mesh_da[4], ++ &path.mesh_da[5], ++ &path.next_hop[0], ++ &path.next_hop[1], ++ &path.next_hop[2], ++ &path.next_hop[3], ++ &path.next_hop[4], ++ &path.next_hop[5], ++ &path.block_mesh_fwd, ++ &path.metadata_type); ++ ++ ++ path.flags |= IEEE80211_MESH_PATH_ACTIVE | IEEE80211_MESH_PATH_RESOLVED; ++ ++ if (ret != 16) ++ return -EINVAL; ++ ++ /* Configure the mpath */ ++ ret = ath11k_nss_mesh_config_path(arvif->ar, arvif, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH, ++ &path); ++ if(ret) { ++ ath11k_warn(arvif->ar->ab, "failed to configure mpath ret %d\n", ret); ++ return -EINVAL; ++ } ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_mpath_add = { ++ .open = simple_open, ++ .write = ath11k_nss_mpath_add, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_mpp_add(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ieee80211_mesh_path_offld path = {0}; ++ u8 buf[128] = {0}; ++ int ret; ++ ++ if (!arvif->ar->ab->nss.debug_mode) { ++ ret = -EPERM; ++ return ret; ++ } ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &path.da[0], ++ &path.da[1], ++ &path.da[2], ++ &path.da[3], ++ &path.da[4], ++ &path.da[5], ++ &path.mesh_da[0], ++ &path.mesh_da[1], ++ &path.mesh_da[2], ++ &path.mesh_da[3], ++ &path.mesh_da[4], ++ &path.mesh_da[5]); ++ ++ path.flags |= IEEE80211_MESH_PATH_ACTIVE | IEEE80211_MESH_PATH_RESOLVED; ++ ++ if (ret != 12) ++ return -EINVAL; ++ ++ /* Configure the mpp */ ++ ret = ath11k_nss_mesh_config_path(arvif->ar, arvif, ++ IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP, ++ &path); ++ if(ret) { ++ ath11k_warn(arvif->ar->ab, "failed to configure mpp ret %d\n", ret); ++ return -EINVAL; ++ } ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_mpp_add = { ++ .open = simple_open, ++ .write = ath11k_nss_mpp_add, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_mpath_update(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ieee80211_mesh_path_offld path = {0}; ++ u8 buf[128] = {0}; ++ int ret; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%u %hhu %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %hhu %lu %hhu %hhu", ++ &path.metric, ++ &path.hop_count, ++ &path.mesh_da[0], ++ &path.mesh_da[1], ++ &path.mesh_da[2], ++ &path.mesh_da[3], ++ &path.mesh_da[4], ++ &path.mesh_da[5], ++ &path.next_hop[0], ++ &path.next_hop[1], ++ &path.next_hop[2], ++ &path.next_hop[3], ++ &path.next_hop[4], ++ &path.next_hop[5], ++ &path.old_next_hop[0], ++ &path.old_next_hop[1], ++ &path.old_next_hop[2], ++ &path.old_next_hop[3], ++ &path.old_next_hop[4], ++ &path.old_next_hop[5], ++ &path.mesh_gate, ++ &path.exp_time, ++ &path.block_mesh_fwd, ++ &path.metadata_type); ++ ++ ++ path.flags |= IEEE80211_MESH_PATH_ACTIVE | IEEE80211_MESH_PATH_RESOLVED; ++ ++ if (ret != 24) ++ return -EINVAL; ++ ++ /* Configure the mpath */ ++ ret = ath11k_nss_mesh_config_path(arvif->ar, arvif, ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH, ++ &path); ++ if(ret) { ++ ath11k_warn(arvif->ar->ab, "failed to configure mpath ret %d\n", ret); ++ return -EINVAL; ++ } ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_mpath_update = { ++ .open = simple_open, ++ .write = ath11k_nss_mpath_update, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_mpp_update(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ieee80211_mesh_path_offld path = {0}; ++ u8 buf[128] = {0}; ++ int ret; ++ ++ if (!arvif->ar->ab->nss.debug_mode) { ++ ret = -EPERM; ++ return ret; ++ } ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &path.da[0], ++ &path.da[1], ++ &path.da[2], ++ &path.da[3], ++ &path.da[4], ++ &path.da[5], ++ &path.mesh_da[0], ++ &path.mesh_da[1], ++ &path.mesh_da[2], ++ &path.mesh_da[3], ++ &path.mesh_da[4], ++ &path.mesh_da[5]); ++ ++ path.flags |= IEEE80211_MESH_PATH_ACTIVE | IEEE80211_MESH_PATH_RESOLVED; ++ ++ if (ret != 12) ++ return -EINVAL; ++ ++ /* Configure the mpp */ ++ ret = ath11k_nss_mesh_config_path(arvif->ar, arvif, ++ IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP, ++ &path); ++ if(ret) { ++ ath11k_warn(arvif->ar->ab, "failed to configure mpp ret %d\n", ret); ++ return -EINVAL; ++ } ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_mpp_update = { ++ .open = simple_open, ++ .write = ath11k_nss_mpp_update, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ ++static ssize_t ath11k_nss_mpath_delete(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ieee80211_mesh_path_offld path = {0}; ++ u8 buf[128] = {0}; ++ int ret; ++ ++ if (!arvif->ar->ab->nss.debug_mode) { ++ ret = -EPERM; ++ return ret; ++ } ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &path.mesh_da[0], ++ &path.mesh_da[1], ++ &path.mesh_da[2], ++ &path.mesh_da[3], ++ &path.mesh_da[4], ++ &path.mesh_da[5], ++ &path.next_hop[0], ++ &path.next_hop[1], ++ &path.next_hop[2], ++ &path.next_hop[3], ++ &path.next_hop[4], ++ &path.next_hop[5]); ++ ++ path.flags |= IEEE80211_MESH_PATH_DELETED; ++ ++ if (ret != 12) ++ return -EINVAL; ++ ++ /* Configure the mpath */ ++ ret = ath11k_nss_mesh_config_path(arvif->ar, arvif, ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH, ++ &path); ++ if(ret) { ++ ath11k_warn(arvif->ar->ab, "failed to configure mpath ret %d\n", ret); ++ return -EINVAL; ++ } ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_mpath_del = { ++ .open = simple_open, ++ .write = ath11k_nss_mpath_delete, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_mpp_delete(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ieee80211_mesh_path_offld path = {0}; ++ u8 buf[128] = {0}; ++ int ret; ++ ++ if (!arvif->ar->ab->nss.debug_mode) { ++ ret = -EPERM; ++ return ret; ++ } ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", ++ &path.da[0], ++ &path.da[1], ++ &path.da[2], ++ &path.da[3], ++ &path.da[4], ++ &path.da[5], ++ &path.mesh_da[0], ++ &path.mesh_da[1], ++ &path.mesh_da[2], ++ &path.mesh_da[3], ++ &path.mesh_da[4], ++ &path.mesh_da[5]); ++ ++ path.flags |= IEEE80211_MESH_PATH_DELETED; ++ ++ if (ret != 12) ++ return -EINVAL; ++ ++ /* Configure the mpp */ ++ ret = ath11k_nss_mesh_config_path(arvif->ar, arvif, ++ IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP, ++ &path); ++ if(ret) { ++ ath11k_warn(arvif->ar->ab, "failed to configure mpp ret %d\n", ret); ++ return -EINVAL; ++ } ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_mpp_del = { ++ .open = simple_open, ++ .write = ath11k_nss_mpp_delete, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ ++static ssize_t ath11k_nss_assoc_link(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ u8 buf[128] = {0}; ++ int ret; ++ u32 assoc_link = 0; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%u", &assoc_link); ++ ++ if (ret != 1) ++ return -EINVAL; ++ ++ arvif->ar->ab->nss.debug_mode = true; ++ arvif->vif->driver_flags |= IEEE80211_VIF_NSS_OFFLOAD_DEBUG_MODE; ++ ++ ret = ath11k_nss_assoc_link_arvif_to_ifnum(arvif, assoc_link); ++ ++ return ret ? ret : count; ++ ++} ++ ++static const struct file_operations fops_nss_assoc_link = { ++ .open = simple_open, ++ .write = ath11k_nss_assoc_link, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_links(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ char buf[512] = {0}; ++ struct arvif_nss *nss; ++ int len = 0; ++ ++ list_for_each_entry(nss, &mesh_vaps, list) ++ len += scnprintf(buf + len, sizeof(buf) - len, "link id %d\n", ++ nss->if_num); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static const struct file_operations fops_nss_links = { ++ .open = simple_open, ++ .read = ath11k_nss_links, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_vap_link_id(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct arvif_nss *nss = &arvif->nss; ++ char buf[512] = {0}; ++ int len = 0; ++ ++ len = scnprintf(buf, sizeof(buf) - len, "link id %d\n", ++ nss->if_num); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static const struct file_operations fops_nss_vap_link_id = { ++ .open = simple_open, ++ .read = ath11k_nss_vap_link_id, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_read_mpp_mode(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ char buf[512] = {0}; ++ int len = 0; ++ ++ len = scnprintf(buf, sizeof(buf) - len, "%s\n",mpp_mode ? ++ "Host Assisted Learning" : "NSS Independent Learning"); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t ath11k_nss_write_mpp_mode(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ u8 buf[128] = {0}; ++ int ret; ++ u32 mppath_mode = 0; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ret = sscanf(buf, "%u", &mppath_mode); ++ ++ if (ret != 1) ++ return -EINVAL; ++ ++ mpp_mode = mppath_mode; ++ ++ ret = 0; ++ ++ return ret ? ret : count; ++} ++ ++static const struct file_operations fops_nss_mpp_mode = { ++ .open = simple_open, ++ .write = ath11k_nss_write_mpp_mode, ++ .read = ath11k_nss_read_mpp_mode, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_write_excep_flags(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ u8 buf[128] = {0}; ++ int ret; ++ struct nss_wifi_mesh_exception_flag_msg msg; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ++ ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %hhu", ++ &msg.dest_mac_addr[0], ++ &msg.dest_mac_addr[1], ++ &msg.dest_mac_addr[2], ++ &msg.dest_mac_addr[3], ++ &msg.dest_mac_addr[4], ++ &msg.dest_mac_addr[5], ++ &msg.exception); ++ ++ if (ret != 7) ++ return -EINVAL; ++ ++ ret = ath11k_nss_mesh_exception_flags(arvif, &msg); ++ ++ return ret ? ret : count; ++} ++ ++static const struct file_operations fops_nss_excep_flags = { ++ .open = simple_open, ++ .write = ath11k_nss_write_excep_flags, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_write_metadata_type(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ struct ath11k *ar = arvif->ar; ++ u8 buf[128] = {0}; ++ int ret; ++ u8 pkt_type; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ++ ret = sscanf(buf, "%hhu", &pkt_type); ++ mutex_lock(&ar->conf_mutex); ++ arvif->nss.metadata_type = pkt_type ? NSS_WIFI_MESH_PRE_HEADER_80211 : NSS_WIFI_MESH_PRE_HEADER_NONE; ++ mutex_unlock(&ar->conf_mutex); ++ ++ if (ret != 1) ++ return -EINVAL; ++ ++ ret = 0; ++ ++ return ret ? ret : count; ++} ++ ++static const struct file_operations fops_nss_metadata_type = { ++ .open = simple_open, ++ .write = ath11k_nss_write_metadata_type, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t ath11k_nss_write_exc_rate_limit(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath11k_vif *arvif = file->private_data; ++ u8 buf[128] = {0}; ++ int ret; ++ struct nss_wifi_mesh_rate_limit_config nss_exc_cfg; ++ ++ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); ++ if (ret < 0) ++ return ret; ++ ++ buf[ret] = '\0'; ++ ++ ret = sscanf(buf, "%u %u %u", ++ &nss_exc_cfg.exception_num, ++ &nss_exc_cfg.enable, ++ &nss_exc_cfg.rate_limit); ++ ++ if (ret != 3) ++ return -EINVAL; ++ ++ ret = ath11k_nss_exc_rate_config(arvif, &nss_exc_cfg); ++ ++ return ret ? ret : count; ++} ++ ++static const struct file_operations fops_nss_exc_rate_limit = { ++ .open = simple_open, ++ .write = ath11k_nss_write_exc_rate_limit, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++void ath11k_debugfs_nss_mesh_vap_create(struct ath11k_vif *arvif) ++{ ++ struct dentry *debugfs_nss_mesh_dir, *debugfs_dbg_infra; ++ ++ debugfs_nss_mesh_dir = debugfs_create_dir("nss_mesh", arvif->vif->debugfs_dir); ++ debugfs_dbg_infra = debugfs_create_dir("dbg_infra", debugfs_nss_mesh_dir); ++ ++ debugfs_create_file("dump_nss_mpath_table", 0600, ++ debugfs_nss_mesh_dir, arvif, ++ &fops_nss_dump_mpath_table); ++ ++ debugfs_create_file("dump_nss_mpp_table", 0600, ++ debugfs_nss_mesh_dir, arvif, ++ &fops_nss_dump_mpp_table); ++ ++ debugfs_create_file("mpath_add", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_mpath_add); ++ ++ debugfs_create_file("mpath_update", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_mpath_update); ++ ++ debugfs_create_file("mpath_del", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_mpath_del); ++ ++ debugfs_create_file("mpp_add", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_mpp_add); ++ ++ debugfs_create_file("mpp_update", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_mpp_update); ++ ++ debugfs_create_file("mpp_del", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_mpp_del); ++ ++ debugfs_create_file("assoc_link", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_assoc_link); ++ ++ debugfs_create_file("vap_linkid", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_vap_link_id); ++ ++ debugfs_create_file("excep_flags", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_excep_flags); ++ ++ debugfs_create_file("metadata_type", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_metadata_type); ++ ++ debugfs_create_file("exc_rate_limit", 0200, ++ debugfs_dbg_infra, arvif, ++ &fops_nss_exc_rate_limit); ++} ++ ++void ath11k_debugfs_nss_soc_create(struct ath11k_base *ab) ++{ ++ struct dentry *debugfs_dbg_infra; ++ ++ debugfs_dbg_infra = debugfs_create_dir("dbg_infra", debugfs_ath11k); ++ ++ debugfs_create_file("links", 0200, ++ debugfs_dbg_infra, ab, ++ &fops_nss_links); ++ ++ debugfs_create_file("mpp_mode", 0600, ++ debugfs_dbg_infra, ab, ++ &fops_nss_mpp_mode); ++} ++ ++#endif +--- /dev/null ++++ b/drivers/net/wireless/ath/ath11k/debug_nss.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: BSD-3-Clause-Clear */ ++/* ++ * Copyright (c) 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#ifndef ATH11K_DEBUG_NSS_H ++#define ATH11K_DEBUG_NSS_H ++ ++#include ++#include ++ ++#define ATH11K_NSS_MPATH_DUMP_TIMEOUT (2 * HZ) ++ ++struct ath11k_vif; ++extern enum nss_wifi_mesh_mpp_learning_mode mpp_mode; ++extern struct list_head mesh_vaps; ++struct ath11k_nss_dbg_priv_data { ++ struct ath11k_vif *arvif; ++ char *buf; ++ unsigned int len; ++}; ++ ++#ifdef CPTCFG_MAC80211_DEBUGFS ++void ath11k_debugfs_nss_mesh_vap_create(struct ath11k_vif *arvif); ++void ath11k_debugfs_nss_soc_create(struct ath11k_base *ab); ++#else ++static inline void ath11k_debugfs_nss_mesh_vap_create(struct ath11k_vif *arvif) ++{ ++} ++static inline void ath11k_debugfs_nss_soc_create(struct ath11k_base *ab) ++{ ++} ++#endif ++ ++#endif +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -1453,15 +1453,29 @@ struct htt_ppdu_stats_usr_cmn_array { + struct htt_tx_ppdu_stats_info tx_ppdu_info[]; + } __packed; + ++#define HTT_PPDU_STATS_CMPLTN_FLUSH_INFO_FLOW_TYPE GENMASK(7, 0) ++#define HTT_PPDU_STATS_CMPLTN_FLUSH_INFO_NUM_MPDU GENMASK(16, 8) ++#define HTT_PPDU_STATS_CMPLTN_FLUSH_INFO_NUM_MSDU GENMASK(30, 17) ++ ++struct htt_ppdu_stats_cmpltn_flush { ++ u32 drop_reason; ++ u32 info; ++ u8 tid_num; ++ u8 queue_type; ++ u16 sw_peer_id; ++} __packed; ++ + struct htt_ppdu_user_stats { + u16 peer_id; + u16 delay_ba; + u32 tlv_flags; + bool is_valid_peer_id; ++ bool rate_stats_updated; + struct htt_ppdu_stats_user_rate rate; + struct htt_ppdu_stats_usr_cmpltn_cmn cmpltn_cmn; + struct htt_ppdu_stats_usr_cmpltn_ack_ba_status ack_ba; + struct htt_ppdu_stats_user_common common; ++ struct htt_ppdu_stats_cmpltn_flush cmpltn_flush; + }; + + #define HTT_PPDU_STATS_MAX_USERS 37 +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1409,6 +1409,71 @@ static int ath11k_htt_tlv_ppdu_stats_par + return 0; + } + ++static void ath11k_dp_ppdu_stats_flush_tlv_parse(struct ath11k_base *ab, ++ struct htt_ppdu_stats_cmpltn_flush *msg) ++{ ++ struct ath11k *ar; ++ struct ieee80211_sta *sta; ++ struct ath11k_sta *arsta; ++ struct ath11k_peer *peer = NULL; ++ struct ieee80211_tx_status status; ++ struct ieee80211_rate_status status_rate = { 0 }; ++ ++ if (!ab->nss.mesh_nss_offload_enabled) ++ return; ++ ++ rcu_read_lock(); ++ ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_id(ab, msg->sw_peer_id); ++ if (!peer) ++ goto exit; ++ ++ if (peer->vif->type != NL80211_IFTYPE_MESH_POINT) ++ goto exit; ++ ++ if (ether_addr_equal(peer->addr, peer->vif->addr)) ++ goto exit; ++ ++ sta = peer->sta; ++ arsta = (struct ath11k_sta *)sta->drv_priv; ++ ++ memset(&status, 0, sizeof(status)); ++ ++ status.sta = sta; ++ status_rate.rate_idx = arsta->last_txrate; ++ ++ status.rates = &status_rate; ++ status.mpdu_fail = FIELD_GET(HTT_PPDU_STATS_CMPLTN_FLUSH_INFO_NUM_MPDU, ++ msg->info); ++ ar = arsta->arvif->ar; ++ ieee80211s_update_metric_ppdu(ar->hw, &status); ++ ++exit: ++ spin_unlock_bh(&ab->base_lock); ++ rcu_read_unlock(); ++} ++ ++static int ath11k_htt_tlv_ppdu_soc_stats_parse(struct ath11k_base *ab, ++ u16 tag, u16 len, const void *ptr, ++ void *data) ++{ ++ switch (tag) { ++ case HTT_PPDU_STATS_TAG_USR_COMPLTN_FLUSH: ++ if (len < sizeof(struct htt_ppdu_stats_cmpltn_flush)) { ++ ath11k_warn(ab, "Invalid len %d for the tag 0x%x\n", ++ len, tag); ++ return -EINVAL; ++ } ++ ath11k_dp_ppdu_stats_flush_tlv_parse(ab, (struct htt_ppdu_stats_cmpltn_flush *)ptr); ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ + static void + ath11k_update_per_peer_tx_stats(struct ath11k *ar, + struct htt_ppdu_stats *ppdu_stats, u8 user) +@@ -1432,6 +1497,9 @@ ath11k_update_per_peer_tx_stats(struct a + if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE))) + return; + ++ if (usr_stats->rate_stats_updated) ++ return; ++ + if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) + is_ampdu = + HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags); +@@ -1565,6 +1633,8 @@ ath11k_update_per_peer_tx_stats(struct a + ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); + } + ++ usr_stats->rate_stats_updated = true; ++ + spin_unlock_bh(&ab->base_lock); + rcu_read_unlock(); + } +@@ -1685,6 +1755,69 @@ int ath11k_dp_htt_tlv_iter(struct ath11k + return 0; + } + ++static void ++ath11k_dp_rx_ppdu_stats_update_tx_comp_status(struct ath11k *ar, ++ struct htt_ppdu_stats_info *ppdu_info) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ieee80211_sta *sta; ++ struct ath11k_sta *arsta; ++ struct ath11k_peer *peer = NULL; ++ struct htt_ppdu_user_stats* usr_stats = NULL; ++ struct ieee80211_tx_status status; ++ struct ieee80211_rate_status status_rate = { 0 }; ++ ++ u32 peer_id = 0; ++ int i; ++ ++ lockdep_assert_held(&ar->data_lock); ++ ++ if (!ar->ab->nss.mesh_nss_offload_enabled) ++ return; ++ ++ ath11k_htt_update_ppdu_stats(ar, &ppdu_info->ppdu_stats); ++ ++ rcu_read_lock(); ++ ++ for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) { ++ usr_stats = &ppdu_info->ppdu_stats.user_stats[i]; ++ peer_id = usr_stats->peer_id; ++ spin_lock_bh(&ab->base_lock); ++ peer = ath11k_peer_find_by_id(ab, peer_id); ++ if (!peer) { ++ spin_unlock_bh(&ab->base_lock); ++ continue; ++ } ++ ++ if (peer->vif->type != NL80211_IFTYPE_MESH_POINT) { ++ spin_unlock_bh(&ab->base_lock); ++ goto exit; ++ } ++ ++ if (ether_addr_equal(peer->addr, peer->vif->addr)) { ++ spin_unlock_bh(&ab->base_lock); ++ continue; ++ } ++ ++ sta = peer->sta; ++ arsta = (struct ath11k_sta *)sta->drv_priv; ++ ++ memset(&status, 0, sizeof(status)); ++ ++ status.sta = sta; ++ status_rate.rate_idx = arsta->last_txrate; ++ status.rates = &status_rate; ++ status.mpdu_succ = usr_stats->cmpltn_cmn.mpdu_success; ++ ++ ieee80211s_update_metric_ppdu(ar->hw, &status); ++ ++ spin_unlock_bh(&ab->base_lock); ++ } ++ ++exit: ++ rcu_read_unlock(); ++} ++ + static int ath11k_htt_pull_ppdu_stats(struct ath11k_base *ab, + struct sk_buff *skb) + { +@@ -1703,6 +1836,15 @@ static int ath11k_htt_pull_ppdu_stats(st + pdev_id = FIELD_GET(HTT_T2H_PPDU_STATS_INFO_PDEV_ID, msg->info); + ppdu_id = msg->ppdu_id; + ++ if (pdev_id == 0) { ++ ret = ath11k_dp_htt_tlv_iter(ab, msg->data, len, ++ ath11k_htt_tlv_ppdu_soc_stats_parse, ++ NULL); ++ if (ret) ++ ath11k_warn(ab, "failed to parse tlv %d\n", ret); ++ return ret; ++ } ++ + rcu_read_lock(); + ar = ath11k_mac_get_ar_by_pdev_id(ab, pdev_id); + if (!ar) { +@@ -1770,6 +1912,12 @@ static int ath11k_htt_pull_ppdu_stats(st + } + } + ++ /* Stats update for mesh interface used when nss-offload in mesh is enabled */ ++ if ((ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA && ++ (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_RATE)) && ++ ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON))) ++ ath11k_dp_rx_ppdu_stats_update_tx_comp_status(ar, ppdu_info); ++ + out_unlock_data: + spin_unlock_bh(&ar->data_lock); + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -3469,6 +3469,18 @@ static void ath11k_mac_op_nss_bss_info_c + ath11k_warn(ar->ab, "failed to set ap_isolate in nss %d\n", ret); + } + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ if (changed & (BSS_CHANGED_NSS_MESH_TTL | ++ BSS_CHANGED_NSS_MESH_REFRESH_TIME | ++ BSS_CHANGED_NSS_MESH_FWD_ENABLED)) { ++ ret = ath11k_nss_mesh_config_update(vif, changed); ++ if (ret) ++ ath11k_warn(ar->ab, ++ "failed to update mesh nss offload configuration %d\n", ++ ret); ++ } ++#endif ++ + mutex_unlock(&ar->conf_mutex); + } + +@@ -9709,6 +9721,28 @@ err_fallback: + return 0; + } + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static void ++ath11k_mac_op_config_mesh_offload_path(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ int ret; ++ ++ if (arvif->ar->ab->nss.debug_mode) { ++ ret = 0; ++ return; ++ } ++ ++ ret = ath11k_nss_mesh_config_path(ar, arvif, cmd, path); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to configure path entry to mesh table %d\n", ret); ++} ++#endif ++ + static const struct ieee80211_ops ath11k_ops = { + .tx = ath11k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, +@@ -9766,6 +9800,9 @@ static const struct ieee80211_ops ath11k + .set_sar_specs = ath11k_mac_op_set_bios_sar_specs, + .remain_on_channel = ath11k_mac_op_remain_on_channel, + .cancel_remain_on_channel = ath11k_mac_op_cancel_remain_on_channel, ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ .config_mesh_offload_path = ath11k_mac_op_config_mesh_offload_path, ++#endif + }; + + static void ath11k_mac_update_ch_list(struct ath11k *ar, +@@ -10227,6 +10264,8 @@ static int __ath11k_mac_register(struct + ieee80211_hw_set(ar->hw, SUPPORTS_NSS_OFFLOAD); + wiphy_ext_feature_set(ar->hw->wiphy, + NL80211_EXT_FEATURE_VLAN_OFFLOAD); ++ if (ab->nss.mesh_nss_offload_enabled) ++ ieee80211_hw_set(ar->hw, SUPPORTS_MESH_NSS_OFFLOAD); + } + + ret = ieee80211_register_hw(ar->hw); +--- a/drivers/net/wireless/ath/ath11k/nss.c ++++ b/drivers/net/wireless/ath/ath11k/nss.c +@@ -6,6 +6,7 @@ + #include "debug.h" + #include "mac.h" + #include "nss.h" ++#include "debug_nss.h" + #include "core.h" + #include "peer.h" + #include "dp_rx.h" +@@ -14,6 +15,11 @@ + #include "wmi.h" + #include "../../../../../net/mac80211/sta_info.h" + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++enum nss_wifi_mesh_mpp_learning_mode mpp_mode = NSS_WIFI_MESH_MPP_LEARNING_MODE_INDEPENDENT_NSS; ++LIST_HEAD(mesh_vaps); ++#endif ++ + /*-----------------------------ATH11K-NSS Helpers--------------------------*/ + + static enum ath11k_nss_opmode +@@ -32,6 +38,30 @@ ath11k_nss_get_vdev_opmode(struct ath11k + return ATH11K_NSS_OPMODE_UNKNOWN; + } + ++static struct ath11k_vif *ath11k_nss_get_arvif_from_dev(struct net_device *dev) ++{ ++ struct wireless_dev *wdev; ++ struct ieee80211_vif *vif; ++ struct ath11k_vif *arvif; ++ ++ if (!dev) ++ return NULL; ++ ++ wdev = dev->ieee80211_ptr; ++ if (!wdev) ++ return NULL; ++ ++ vif = wdev_to_ieee80211_vif(wdev); ++ if (!vif) ++ return NULL; ++ ++ arvif = (struct ath11k_vif *)vif->drv_priv; ++ if (!arvif) ++ return NULL; ++ ++ return arvif; ++} ++ + static void ath11k_nss_wifili_stats_sync(struct ath11k_base *ab, + struct nss_wifili_stats_sync_msg *wlsoc_stats) + { +@@ -263,7 +293,6 @@ void ath11k_nss_wifili_event_receive(str + ab->nss.response = response; + complete(&ab->nss.complete); + break; +- + case NSS_WIFILI_PEER_CREATE_MSG: + if (response != NSS_CMN_RESPONSE_EMSG) + break; +@@ -333,6 +362,13 @@ void ath11k_nss_wifili_event_receive(str + ath11k_dbg(ab, ATH11K_DBG_NSS_WDS, "nss wifili peer 4addr event received %d response %d error %d\n", + msg_type, response, error); + break; ++ case NSS_WIFILI_SEND_MESH_CAPABILITY_INFO: ++ complete(&ab->nss.complete); ++ if (response != NSS_CMN_RESPONSE_EMSG) ++ ab->nss.mesh_nss_offload_enabled = true; ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, "nss wifili mesh capability response %d\n", ++ ab->nss.mesh_nss_offload_enabled); ++ break; + default: + ath11k_dbg(ab, ATH11K_DBG_NSS, "unhandled event %d\n", msg_type); + break; +@@ -420,7 +456,9 @@ ath11k_nss_wifili_ext_callback_fn(struct + ath11k_nss_process_mic_error(ab, skb); + break; + default: +- kfree(skb); ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unknown packet type received in wifili ext cb %d", ++ wepm->pkt_type); ++ dev_kfree_skb_any(skb); + break; + } + } +@@ -735,8 +773,6 @@ ath11k_nss_vdev_special_data_receive(str + { + struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL; + struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL; +- struct wireless_dev *wdev; +- struct ieee80211_vif *vif; + struct ath11k_vif *arvif; + struct ath11k_base *ab; + bool drop = false; +@@ -744,24 +780,7 @@ ath11k_nss_vdev_special_data_receive(str + int data_offs = 0; + int ret = 0; + +- if (!dev) { +- dev_kfree_skb_any(skb); +- return; +- } +- +- wdev = dev->ieee80211_ptr; +- if (!wdev) { +- dev_kfree_skb_any(skb); +- return; +- } +- +- vif = wdev_to_ieee80211_vif(wdev); +- if (!vif) { +- dev_kfree_skb_any(skb); +- return; +- } +- +- arvif = (struct ath11k_vif *)vif->drv_priv; ++ arvif = ath11k_nss_get_arvif_from_dev(dev); + if (!arvif) { + dev_kfree_skb_any(skb); + return; +@@ -874,25 +893,1041 @@ static void + ath11k_nss_ext_vdev_data_receive(struct net_device *dev, struct sk_buff *skb, + __attribute__((unused)) struct napi_struct *napi) + { +- struct wireless_dev *wdev; +- struct ieee80211_vif *vif; + struct ath11k_vif *arvif; + struct ath11k_base *ab; + bool eth_decap = false; + int data_offs = 0; + int ret; + +- if (!dev) { ++ arvif = ath11k_nss_get_arvif_from_dev(dev); ++ if (!arvif) { + dev_kfree_skb_any(skb); + return; + } + +- wdev = dev->ieee80211_ptr; +- if (!wdev) { ++ ab = arvif->ar->ab; ++ ++ skb->dev = dev; ++ ++ /* log the original skb received from nss */ ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "dp rx msdu from nss ext : ", ++ skb->data, skb->len); ++ ++ ret = ath11k_nss_undecap(arvif, skb, &data_offs, ð_decap); ++ if (ret) { ++ ath11k_warn(ab, "error in nss ext rx undecap, type %d err %d\n", ++ arvif->nss.decap, ret); ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++} ++ ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++/*------Mesh offload------*/ ++ ++void ath11k_nss_mesh_wifili_event_receive(void *app_data, ++ struct nss_cmn_msg *cmn_msg) ++{ ++ struct nss_wifi_mesh_msg *msg = (struct nss_wifi_mesh_msg *)cmn_msg; ++ struct ath11k_base *ab = app_data; ++ u32 msg_type = msg->cm.type; ++ enum nss_cmn_response response = msg->cm.response; ++ u32 error = msg->cm.error; ++ ++ if (!ab) ++ return; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, "nss mesh event received %d response %d error %d\n", ++ msg_type, response, error); ++ ++ switch (msg_type) { ++ case NSS_WIFI_MESH_MSG_MPATH_ADD: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab,"failed to add an entry to mpath table mesh_da %pM vdev_id %d\n", ++ (&msg->msg.mpath_add)->dest_mac_addr, ++ (&msg->msg.mpath_add)->link_vap_id); ++ break; ++ case NSS_WIFI_MESH_MSG_MPATH_UPDATE: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab, "failed to update mpath entry mesh_da %pM vdev_id %d" ++ "next_hop %pM old_next_hop %pM metric %d flags 0x%u hop_count %d" ++ "exp_time %u mesh_gate %u\n", ++ (&msg->msg.mpath_update)->dest_mac_addr, ++ (&msg->msg.mpath_update)->link_vap_id, ++ (&msg->msg.mpath_update)->next_hop_mac_addr, ++ (&msg->msg.mpath_update)->old_next_hop_mac_addr, ++ (&msg->msg.mpath_update)->metric, ++ (&msg->msg.mpath_update)->path_flags, ++ (&msg->msg.mpath_update)->hop_count, ++ (&msg->msg.mpath_update)->expiry_time, ++ (&msg->msg.mpath_update)->is_mesh_gate); ++ break; ++ case NSS_WIFI_MESH_MSG_MPATH_DELETE: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab,"failed to remove mpath entry mesh_da %pM" ++ "vdev_id %d\n", ++ (&msg->msg.mpath_del)->mesh_dest_mac_addr, ++ (&msg->msg.mpath_del)->link_vap_id); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_ADD: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab,"failed to add proxy entry da %pM mesh_da %pM \n", ++ (&msg->msg.proxy_add_msg)->dest_mac_addr, ++ (&msg->msg.proxy_add_msg)->mesh_dest_mac); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_UPDATE: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab,"failed to update proxy path da %pM mesh_da %pM\n", ++ (&msg->msg.proxy_update_msg)->dest_mac_addr, ++ (&msg->msg.proxy_update_msg)->mesh_dest_mac); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_DELETE: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab,"failed to remove proxy path entry da %pM mesh_da %pM\n", ++ (&msg->msg.proxy_del_msg)->dest_mac_addr, ++ (&msg->msg.proxy_del_msg)->mesh_dest_mac_addr); ++ break; ++ case NSS_WIFI_MESH_MSG_EXCEPTION_FLAG: ++ if (response == NSS_CMN_RESPONSE_EMSG) ++ ath11k_warn(ab,"failed to add the exception da %pM\n", ++ (&msg->msg.exception_msg)->dest_mac_addr); ++ break; ++ default: ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, "unhandled event %d\n", msg_type); ++ break; ++ } ++} ++ ++static void nss_mesh_convert_path_flags(u8 *dest, u8 *src, bool to_nss) ++{ ++ if (to_nss) { ++ if (*src & IEEE80211_MESH_PATH_ACTIVE) ++ *dest |= NSS_WIFI_MESH_PATH_FLAG_ACTIVE; ++ if (*src & IEEE80211_MESH_PATH_RESOLVING) ++ *dest |= NSS_WIFI_MESH_PATH_FLAG_RESOLVING; ++ if (*src & IEEE80211_MESH_PATH_RESOLVED) ++ *dest |= NSS_WIFI_MESH_PATH_FLAG_RESOLVED; ++ if (*src & IEEE80211_MESH_PATH_FIXED) ++ *dest |= NSS_WIFI_MESH_PATH_FLAG_FIXED; ++ } else { ++ if (*src & NSS_WIFI_MESH_PATH_FLAG_ACTIVE) ++ *dest |= IEEE80211_MESH_PATH_ACTIVE; ++ if (*src & NSS_WIFI_MESH_PATH_FLAG_RESOLVING) ++ *dest |= IEEE80211_MESH_PATH_RESOLVING; ++ if (*src & NSS_WIFI_MESH_PATH_FLAG_RESOLVED) ++ *dest |= IEEE80211_MESH_PATH_RESOLVED; ++ if (*src & NSS_WIFI_MESH_PATH_FLAG_FIXED) ++ *dest |= IEEE80211_MESH_PATH_FIXED; ++ } ++} ++ ++static void ath11k_nss_mesh_mpath_refresh(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_path_refresh_msg *refresh_msg; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ refresh_msg = &msg->msg.path_refresh_msg; ++ ether_addr_copy(path.mesh_da, refresh_msg->dest_mac_addr); ++ ether_addr_copy(path.next_hop, refresh_msg->next_hop_mac_addr); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh path refresh event from nss, mDA %pM next_hop %pM link_vdev %d\n", ++ refresh_msg->dest_mac_addr, refresh_msg->next_hop_mac_addr, ++ refresh_msg->link_vap_id); ++ ++ ++ if (ab->nss.debug_mode) ++ return; ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_REFRESH); ++ if (ret) ++ ath11k_warn(ab, "failed to notify mpath refresh nss event %d\n", ret); ++} ++ ++static void ath11k_nss_mesh_path_not_found(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_mpath_not_found_msg *err_msg; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ err_msg = &msg->msg.mpath_not_found_msg; ++ ether_addr_copy(path.da, err_msg->dest_mac_addr); ++ if (err_msg->is_mesh_forward_path) ++ ether_addr_copy(path.ta, err_msg->transmitter_mac_addr); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh path not found event from nss, (m)DA %pM ta %pM link vap %d\n", ++ err_msg->dest_mac_addr, err_msg->transmitter_mac_addr, err_msg->link_vap_id); ++ ++ ++ if (ab->nss.debug_mode) ++ return; ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_PATH_NOT_FOUND); ++ if (ret) ++ ath11k_warn(ab, "failed to notify mpath not found nss event %d\n", ret); ++} ++ ++static void ath11k_nss_mesh_path_delete(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_mpath_del_msg *del_msg = &msg->msg.mpath_del; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ ether_addr_copy(path.mesh_da, del_msg->mesh_dest_mac_addr); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh path delete event from nss, mDA %pM vap_id %d\n", ++ del_msg->mesh_dest_mac_addr, del_msg->link_vap_id); ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_DEL); ++ if (ret) ++ ath11k_warn(ab, "failed to notify mpath delete nss event %d\n", ret); ++} ++ ++static void ath11k_nss_mesh_path_expiry(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_path_expiry_msg *exp_msg = &msg->msg.path_expiry_msg; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ ether_addr_copy(path.mesh_da, exp_msg->mesh_dest_mac_addr); ++ ether_addr_copy(path.next_hop, exp_msg->next_hop_mac_addr); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh path delete event from nss, mDA %pM next_hop %pM if_num %d\n", ++ exp_msg->mesh_dest_mac_addr, exp_msg->next_hop_mac_addr, ++ arvif->nss.if_num); ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPATH_EXP); ++ if (ret) ++ ath11k_warn(ab, "failed to notify mpath expiry nss event %d\n", ret); ++} ++ ++static void ath11k_nss_mesh_mpp_learn(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++ { ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_proxy_path_learn_msg *learn_msg; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ learn_msg = &msg->msg.proxy_learn_msg; ++ ++ ether_addr_copy(path.mesh_da, learn_msg->mesh_dest_mac); ++ ether_addr_copy(path.da, learn_msg->dest_mac_addr); ++ nss_mesh_convert_path_flags(&path.flags, &learn_msg->path_flags, false); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh proxy learn event from nss, mDA %pM da %pM flags 0x%x if_num %d\n", ++ learn_msg->mesh_dest_mac, learn_msg->dest_mac_addr, ++ learn_msg->path_flags, arvif->nss.if_num); ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_LEARN); ++ if (ret) ++ ath11k_warn(ab, "failed to notify proxy learn event %d\n", ret); ++} ++ ++static void ath11k_nss_mesh_mpp_add(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_proxy_path_add_msg *add_msg = &msg->msg.proxy_add_msg; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ ether_addr_copy(path.mesh_da, add_msg->mesh_dest_mac); ++ ether_addr_copy(path.da, add_msg->dest_mac_addr); ++ nss_mesh_convert_path_flags(&path.flags, &add_msg->path_flags, false); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh proxy add event from nss, mDA %pM da %pM flags 0x%x if_num %d\n", ++ add_msg->mesh_dest_mac, add_msg->dest_mac_addr, add_msg->path_flags, ++ arvif->nss.if_num); ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_ADD); ++ if (ret) ++ ath11k_warn(ab, "failed to notify proxy add event %d\n", ret); ++} ++ ++static void ath11k_nss_mesh_mpp_update(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_proxy_path_update_msg *umsg; ++ struct ieee80211_mesh_path_offld path = {0}; ++ int ret; ++ ++ umsg = &msg->msg.proxy_update_msg; ++ ether_addr_copy(path.mesh_da, umsg->mesh_dest_mac); ++ ether_addr_copy(path.da, umsg->dest_mac_addr); ++ nss_mesh_convert_path_flags(&path.flags, &umsg->path_flags, false); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "Mesh proxy update event from nss, mDA %pM da %pM flags 0x%x if_num %d\n", ++ umsg->mesh_dest_mac, umsg->dest_mac_addr, umsg->path_flags, arvif->nss.if_num); ++ ++ ret = ieee80211_mesh_path_offld_change_notify(arvif->vif, &path, ++ IEEE80211_MESH_PATH_OFFLD_ACTION_MPP_UPDATE); ++ if (ret) ++ ath11k_warn(ab, "failed to notify proxy update event %d\n", ret); ++} ++ ++static int ++ath11k_nss_mesh_process_path_table_dump_msg(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct nss_wifi_mesh_path_table_dump *mpath_dump = &msg->msg.mpath_table_dump; ++ struct ath11k_nss_mpath_entry *entry; ++ struct ath11k *ar = arvif->ar; ++ ssize_t len; ++ ++ len = sizeof(struct nss_wifi_mesh_path_dump_entry) * mpath_dump->num_entries; ++ entry = kzalloc(sizeof(*entry) + len, GFP_ATOMIC); ++ if (!entry) ++ return -ENOMEM; ++ ++ memcpy(entry->mpath, mpath_dump->path_entry, len); ++ entry->num_entries = mpath_dump->num_entries; ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_add_tail(&entry->list, &arvif->nss.mpath_dump); ++ arvif->nss.mpath_dump_num_entries += mpath_dump->num_entries; ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ if (!mpath_dump->more_events) ++ complete(&arvif->nss.dump_mpath_complete); ++ ++ return 0; ++} ++ ++static int ++ath11k_nss_mesh_process_mpp_table_dump_msg(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_msg *msg) ++{ ++ struct nss_wifi_mesh_proxy_path_table_dump *mpp_dump; ++ struct ath11k_nss_mpp_entry *entry, *tmp; ++ struct ath11k *ar = arvif->ar; ++ struct arvif_nss *nss = &arvif->nss; ++ ssize_t len; ++ LIST_HEAD(local_entry_exp_update); ++ ++ mpp_dump = &msg->msg.proxy_path_table_dump; ++ ++ if (!mpp_dump->num_entries) ++ return 0; ++ ++ len = sizeof(struct nss_wifi_mesh_proxy_path_dump_entry) * mpp_dump->num_entries; ++ entry = kzalloc(sizeof(*entry) + len, GFP_ATOMIC); ++ if (!entry) ++ return -ENOMEM; ++ ++ memcpy(entry->mpp, mpp_dump->path_entry, len); ++ entry->num_entries = mpp_dump->num_entries; ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_add_tail(&entry->list, &arvif->nss.mpp_dump); ++ arvif->nss.mpp_dump_num_entries += mpp_dump->num_entries; ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ if (!mpp_dump->more_events) { ++ if (arvif->nss.mpp_aging) { ++ arvif->nss.mpp_aging = false; ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&nss->mpp_dump, &local_entry_exp_update); ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(entry, tmp, &local_entry_exp_update, list) { ++ if (entry->mpp->time_diff > ATH11K_MPP_EXPIRY_TIMER_INTERVAL_MS) ++ continue; ++ mesh_nss_offld_proxy_path_exp_update(arvif->vif, ++ entry->mpp->dest_mac_addr, ++ entry->mpp->mesh_dest_mac, ++ entry->mpp->time_diff); ++ } ++ /* If mpp_dump_req is true dont free the entry ++ * since it will get freed in debug_nss_fill_mpp_dump ++ * both mpp_aging and mpp_dump_req will be true during ++ * simultaneous accessing of mpp dump entry. So this will ++ * gain the reuse of same dump result for both mpp_aging ++ * and mpp_dump_req */ ++ if (!arvif->nss.mpp_dump_req) { ++ list_for_each_entry_safe(entry, tmp, &local_entry_exp_update, list) ++ kfree(entry); ++ } else { ++ /* Adding back to global nss dump tbl to reuse the same ++ * tbl for mpp dump request ++ */ ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&local_entry_exp_update, &nss->mpp_dump); ++ spin_unlock_bh(&ar->nss.dump_lock); ++ } ++ } ++ ++ if (arvif->nss.mpp_dump_req) { ++ complete(&arvif->nss.dump_mpp_complete); ++ arvif->nss.mpp_dump_req = false; ++ } ++ } ++ ++ return 0; ++} ++ ++int ath11k_nss_mesh_exception_flags(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_exception_flag_msg *nss_msg) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_path_exception(arvif->nss.mesh_handle, nss_msg, ++ msg_cb, arvif->ar->ab); ++ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(arvif->ar->ab, "failed to set the exception flags\n"); ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++int ath11k_nss_exc_rate_config(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_rate_limit_config *nss_exc_cfg) ++{ ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_config_mesh_exception_sync(arvif->nss.mesh_handle, nss_exc_cfg); ++ ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(arvif->ar->ab, "failed to set the exception rate ctrl\n"); ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static void ath11k_nss_mesh_obj_vdev_event_receive(void *dev, ++ struct nss_cmn_msg *cmn_msg) ++{ ++ struct nss_wifi_mesh_msg *msg = (struct nss_wifi_mesh_msg *) cmn_msg; ++ struct ath11k_base *ab; ++ struct ath11k_vif *arvif; ++ int ret; ++ ++ arvif = ath11k_nss_get_arvif_from_dev(dev); ++ if (!arvif) ++ return; ++ ++ ab = arvif->ar->ab; ++ ++ switch (msg->cm.type) { ++ case NSS_WIFI_MESH_MSG_PATH_REFRESH: ++ ath11k_nss_mesh_mpath_refresh(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_PATH_NOT_FOUND: ++ ath11k_nss_mesh_path_not_found(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_MPATH_DELETE: ++ ath11k_nss_mesh_path_delete(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_PATH_EXPIRY: ++ ath11k_nss_mesh_path_expiry(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_LEARN: ++ ath11k_nss_mesh_mpp_learn(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_ADD: ++ ath11k_nss_mesh_mpp_add(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_UPDATE: ++ ath11k_nss_mesh_mpp_update(arvif, msg); ++ break; ++ case NSS_WIFI_MESH_MSG_PATH_TABLE_DUMP: ++ ret = ath11k_nss_mesh_process_path_table_dump_msg(arvif, msg); ++ if (ret) ++ ath11k_warn(arvif->ar->ab, "failed mpath table dump message %d\n", ++ ret); ++ break; ++ case NSS_WIFI_MESH_MSG_PROXY_PATH_TABLE_DUMP: ++ ret = ath11k_nss_mesh_process_mpp_table_dump_msg(arvif, msg); ++ if (ret) ++ ath11k_warn(arvif->ar->ab, "failed mpp table dump message %d\n", ++ ret); ++ break; ++ default: ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "unknown message type on mesh obj vap %d\n", ++ msg->cm.type); ++ break; ++ } ++} ++ ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static int ath11k_nss_mesh_mpath_add(struct ath11k_vif *arvif, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct nss_wifi_mesh_mpath_add_msg *msg; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_MESH, "add mpath for mesh_da %pM on radio %d\n", ++ path->mesh_da, ar->pdev->pdev_id); ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_mpath_add_msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ ether_addr_copy(msg->dest_mac_addr, path->mesh_da); ++ ether_addr_copy(msg->next_hop_mac_addr, path->next_hop); ++ msg->hop_count = path->hop_count; ++ msg->metric = path->metric; ++ nss_mesh_convert_path_flags(&msg->path_flags, &path->flags, true); ++ msg->link_vap_id = arvif->nss.if_num; ++ msg->block_mesh_fwd = path->block_mesh_fwd; ++ msg->metadata_type = path->metadata_type ? NSS_WIFI_MESH_PRE_HEADER_80211: NSS_WIFI_MESH_PRE_HEADER_NONE; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_path_add(arvif->nss.mesh_handle, msg, ++ msg_cb, ar->ab); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, ++ "failed to add mpath entry mesh_da %pM radio_id %d status %d\n", ++ path->mesh_da, arvif->nss.if_num, status); ++ ret = -EINVAL; ++ } ++ ++ kfree(msg); ++ ++ return ret; ++} ++ ++static int ath11k_nss_mesh_mpath_update(struct ath11k_vif *arvif, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct nss_wifi_mesh_mpath_update_msg *msg; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_MESH, ++ "update mpath mesh_da %pM radio %d next_hop %pM old_next_hop %pM " ++ "metric %d flags 0x%x hop_count %d " ++ "exp_time %lu mesh_gate %d\n", ++ path->mesh_da, ar->pdev->pdev_id, path->next_hop, path->old_next_hop, ++ path->metric, path->flags, path->hop_count, path->exp_time, ++ path->mesh_gate); ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_mpath_update_msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ ether_addr_copy(msg->dest_mac_addr, path->mesh_da); ++ ether_addr_copy(msg->next_hop_mac_addr, path->next_hop); ++ ether_addr_copy(msg->old_next_hop_mac_addr, path->old_next_hop); ++ msg->hop_count = path->hop_count; ++ msg->metric = path->metric; ++ nss_mesh_convert_path_flags(&msg->path_flags, &path->flags, true); ++ msg->link_vap_id = arvif->nss.if_num; ++ msg->is_mesh_gate = path->mesh_gate; ++ msg->expiry_time = path->exp_time; ++ msg->block_mesh_fwd = path->block_mesh_fwd; ++ msg->metadata_type = ++ (uint8_t)(path->metadata_type == ++ (uint8_t) ++ NSS_WIFI_MESH_PRE_HEADER_80211 ? ++ NSS_WIFI_MESH_PRE_HEADER_80211 : ++ NSS_WIFI_MESH_PRE_HEADER_NONE); ++ ++ msg->update_flags = NSS_WIFI_MESH_PATH_UPDATE_FLAG_NEXTHOP | ++ NSS_WIFI_MESH_PATH_UPDATE_FLAG_HOPCOUNT | ++ NSS_WIFI_MESH_PATH_UPDATE_FLAG_METRIC | ++ NSS_WIFI_MESH_PATH_UPDATE_FLAG_MESH_FLAGS | ++ NSS_WIFI_MESH_PATH_UPDATE_FLAG_BLOCK_MESH_FWD | ++ NSS_WIFI_MESH_PATH_UPDATE_FLAG_METADATA_ENABLE_VALID; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_path_update(arvif->nss.mesh_handle, msg, ++ msg_cb, ar->ab); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, ++ "failed to update mpath entry mesh_da %pM radio_id %d status %d\n", ++ path->mesh_da, arvif->nss.if_num, status); ++ ret = -EINVAL; ++ } ++ ++ kfree(msg); ++ ++ return ret; ++} ++ ++static int ath11k_nss_mesh_mpath_del(struct ath11k_vif *arvif, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct nss_wifi_mesh_mpath_del_msg *msg; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_MESH, "del mpath for mesh_da %pM on radio %d\n", ++ path->mesh_da, ar->pdev->pdev_id); ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_mpath_del_msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ ether_addr_copy(msg->mesh_dest_mac_addr, path->mesh_da); ++ ether_addr_copy(msg->next_hop_mac_addr, path->next_hop); ++ msg->link_vap_id = arvif->nss.if_num; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_path_delete(arvif->nss.mesh_handle, ++ msg, msg_cb, ar->ab); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, ++ "failed to del mpath entry mesh_da %pM radio_id %d status %d\n", ++ path->mesh_da, arvif->nss.if_num, status); ++ ret = -EINVAL; ++ } ++ ++ kfree(msg); ++ ++ return ret; ++} ++ ++static int ath11k_nss_mesh_mpp_add_cmd(struct ath11k_vif *arvif, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct nss_wifi_mesh_proxy_path_add_msg *msg; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_MESH, "add mpp mesh_da %pM da %pM\n", ++ path->mesh_da, path->da); ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_proxy_path_add_msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ ether_addr_copy(msg->dest_mac_addr, path->da); ++ ether_addr_copy(msg->mesh_dest_mac, path->mesh_da); ++ nss_mesh_convert_path_flags(&msg->path_flags, &path->flags, true); ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_proxy_path_add(arvif->nss.mesh_handle, ++ msg, msg_cb, ar->ab); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, ++ "failed to add mpp entry da %pM mesh_da %pM status %d\n", ++ path->da, path->mesh_da, status); ++ ret = -EINVAL; ++ } ++ ++ kfree(msg); ++ ++ return ret; ++} ++ ++static int ath11k_nss_mesh_mpp_update_cmd(struct ath11k_vif *arvif, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct nss_wifi_mesh_proxy_path_update_msg *msg; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_MESH, "update mpp da %pM mesh_da %pM on vap_id %d\n", ++ path->da, path->mesh_da, arvif->nss.if_num); ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_proxy_path_update_msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ ether_addr_copy(msg->dest_mac_addr, path->da); ++ ether_addr_copy(msg->mesh_dest_mac, path->mesh_da); ++ nss_mesh_convert_path_flags(&msg->path_flags, &path->flags, true); ++ msg->bitmap = NSS_WIFI_MESH_PATH_UPDATE_FLAG_NEXTHOP | ++ NSS_WIFI_MESH_PATH_UPDATE_FLAG_HOPCOUNT; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_proxy_path_update(arvif->nss.mesh_handle, ++ msg, msg_cb, ar->ab); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, ++ "failed to update mpp da %pM mesh_da %pM status %d\n", ++ path->da, path->mesh_da, status); ++ ret = -EINVAL; ++ } ++ ++ kfree(msg); ++ ++ return ret; ++} ++ ++static int ath11k_nss_mesh_mpp_del_cmd(struct ath11k_vif *arvif, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct nss_wifi_mesh_proxy_path_del_msg *msg; ++ struct ath11k *ar = arvif->ar; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ ath11k_dbg(ar->ab, ATH11K_DBG_NSS_MESH, "del mpath for mesh_da %pM\n", ++ path->mesh_da); ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_proxy_path_del_msg), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ ether_addr_copy(msg->dest_mac_addr, path->da); ++ ether_addr_copy(msg->mesh_dest_mac_addr, path->mesh_da); ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_proxy_path_delete(arvif->nss.mesh_handle, msg, ++ msg_cb, ar->ab); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, ++ "failed to add mpath entry mesh_da %pM status %d\n", ++ path->mesh_da, status); ++ ret = -EINVAL; ++ } ++ ++ kfree(msg); ++ ++ return ret; ++} ++ ++int ath11k_nss_mesh_config_path(struct ath11k *ar, struct ath11k_vif *arvif, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ int ret; ++ ++ ++ if (!ar->ab->nss.enabled) ++ return 0; ++ ++ switch (cmd) { ++ case IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPATH: ++ ret = ath11k_nss_mesh_mpath_add(arvif, path); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPATH: ++ ret = ath11k_nss_mesh_mpath_update(arvif, path); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPATH: ++ ret = ath11k_nss_mesh_mpath_del(arvif, path); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_CMD_ADD_MPP: ++ ret = ath11k_nss_mesh_mpp_add_cmd(arvif, path); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_CMD_UPDATE_MPP: ++ ret = ath11k_nss_mesh_mpp_update_cmd(arvif, path); ++ break; ++ case IEEE80211_MESH_PATH_OFFLD_CMD_DELETE_MPP: ++ ret = ath11k_nss_mesh_mpp_del_cmd(arvif, path); ++ break; ++ default: ++ ath11k_warn(ar->ab, "unknown mesh path table command type %d\n", cmd); ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++int ath11k_nss_mesh_config_update(struct ieee80211_vif *vif, int changed) ++{ ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_config_msg *nss_msg; ++ struct arvif_nss *nss = &arvif->nss; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ if (!ab->nss.enabled) ++ return 0; ++ ++ if (!ab->nss.mesh_nss_offload_enabled) ++ return -ENOTSUPP; ++ ++ if (!changed) ++ return 0; ++ ++ nss_msg = kzalloc(sizeof(*nss_msg), GFP_KERNEL); ++ if (!nss_msg) ++ return -ENOMEM; ++ ++ if (changed & BSS_CHANGED_NSS_MESH_TTL) { ++ nss_msg->ttl = vif->bss_conf.nss_offld_ttl; ++ nss->mesh_ttl = vif->bss_conf.nss_offld_ttl; ++ nss_msg->config_flags |= NSS_WIFI_MESH_CONFIG_FLAG_TTL_VALID; ++ } ++ ++ if (changed & BSS_CHANGED_NSS_MESH_REFRESH_TIME) { ++ nss_msg->mesh_path_refresh_time = ++ vif->bss_conf.nss_offld_mpath_refresh_time; ++ nss->mpath_refresh_time = ++ vif->bss_conf.nss_offld_mpath_refresh_time; ++ nss_msg->config_flags |= NSS_WIFI_MESH_CONFIG_FLAG_MPATH_REFRESH_VALID; ++ } ++ ++ if (changed & BSS_CHANGED_NSS_MESH_FWD_ENABLED) { ++ nss_msg->block_mesh_forwarding = ++ vif->bss_conf.nss_offld_mesh_forward_enabled; ++ nss->mesh_forward_enabled = ++ vif->bss_conf.nss_offld_mesh_forward_enabled; ++ nss_msg->config_flags |= NSS_WIFI_MESH_CONFIG_FLAG_BLOCK_MESH_FWD_VALID; ++ nss_msg->metadata_type = arvif->nss.metadata_type; ++ nss_msg->config_flags |= NSS_WIFI_MESH_CONFIG_FLAG_METADATA_ENABLE_VALID; ++ } ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_mesh_config_update_sync(arvif->nss.mesh_handle, ++ nss_msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failed to configure nss mesh obj vdev nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ } ++ ++ kfree(nss_msg); ++ ++ return ret; ++} ++#endif ++ ++int ath11k_nss_dump_mpath_request(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct ath11k *ar = arvif->ar; ++ struct arvif_nss *nss = &arvif->nss; ++ struct ath11k_nss_mpath_entry *entry, *tmp; ++ LIST_HEAD(local_entry); ++ nss_tx_status_t status; ++ ++ /* Clean up any stale entries from old events */ ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail(&nss->mpath_dump, &local_entry); ++ arvif->nss.mpath_dump_num_entries = 0; ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(entry, tmp, &local_entry, list) ++ kfree(entry); ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_dump_mesh_path_sync(arvif->nss.mesh_handle); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failed to send mpath dump command on mesh obj vdev nss_err:%d\n", ++ status); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++int ath11k_nss_dump_mpp_request(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct ath11k *ar = arvif->ar; ++ struct arvif_nss *nss = &arvif->nss; ++ struct ath11k_nss_mpp_entry *entry, *tmp; ++ LIST_HEAD(local_entry); ++ nss_wifi_meshmgr_status_t status; ++ ++ if (!arvif->nss.mpp_aging) { ++ /* Clean up any stale entries from old events */ ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&nss->mpp_dump, &local_entry); ++ arvif->nss.mpp_dump_num_entries = 0; ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(entry, tmp, &local_entry, list) { ++ list_del(&entry->list); ++ kfree(entry); ++ } ++ } ++ ++ arvif->nss.mpp_dump_req = true; ++ ++ status = nss_wifi_meshmgr_dump_mesh_proxy_path_sync(arvif->nss.mesh_handle); ++ if (status != NSS_WIFI_MESHMGR_SUCCESS) { ++ if (status == NSS_WIFI_MESHMGR_FAILURE_ONESHOT_ALREADY_ATTACHED) ++ return 0; ++ ath11k_warn(ab, "failed to send mpp dump command on mesh obj vdev nss_err:%d\n", ++ status); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++void ath11k_nss_mpp_timer_cb(struct timer_list *timer) ++{ ++ nss_wifi_mesh_msg_callback_t msg_cb; ++ struct arvif_nss *nss = from_timer(nss, timer,mpp_expiry_timer); ++ struct ath11k_vif *arvif = container_of(nss, struct ath11k_vif, nss); ++ struct ath11k_base *ab = arvif->ar->ab; ++ LIST_HEAD(local_entry); ++ nss_tx_status_t status; ++ ++ msg_cb = (nss_wifi_mesh_msg_callback_t)ath11k_nss_mesh_wifili_event_receive; ++ ++ if (!arvif->nss.mpp_dump_req) ++ arvif->nss.mpp_dump_num_entries = 0; ++ arvif->nss.mpp_aging = true; ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_dump_mesh_proxy_path(arvif->nss.mesh_handle, msg_cb, ab); ++ if (status != NSS_TX_SUCCESS) ++ ath11k_warn(ab, "failed to send mpp dump command from timer nss_err:%d\n", ++ status); ++ ++ mod_timer(&nss->mpp_expiry_timer, ++ jiffies + msecs_to_jiffies(ATH11K_MPP_EXPIRY_TIMER_INTERVAL_MS)); ++ ++} ++ ++static void ++ath11k_nss_mesh_obj_vdev_data_receive(struct net_device *dev, struct sk_buff *skb, ++ struct napi_struct *napi) ++{ ++ struct ath11k_vif *arvif; ++ struct ath11k_base *ab; ++ char dump_msg[100] = {0}; ++ struct nss_wifi_mesh_per_packet_metadata *wifi_metadata = NULL; ++ ++ arvif = ath11k_nss_get_arvif_from_dev(dev); ++ if (!arvif) { + dev_kfree_skb_any(skb); + return; + } + ++ ab = arvif->ar->ab; ++ ++ skb->dev = dev; ++ ++ snprintf(dump_msg, sizeof(dump_msg), "nss mesh obj vdev: link id %d ", ++ arvif->nss.if_num); ++ ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "dp rx msdu from nss", dump_msg, ++ skb->data, skb->len); ++ ++ if (arvif->nss.metadata_type == NSS_WIFI_MESH_PRE_HEADER_80211) { ++ wifi_metadata = (struct nss_wifi_mesh_per_packet_metadata *)(skb->data - ++ (sizeof(struct nss_wifi_mesh_per_packet_metadata))); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, ++ "exception from nss on mesh obj vap: pkt_type %d\n", ++ wifi_metadata->pkt_type); ++ switch (wifi_metadata->pkt_type) { ++ case NSS_WIFI_MESH_PRE_HEADER_80211: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "wifi header from nss on mesh obj vdev: ", ++ skb->data - sizeof(*wifi_metadata), sizeof(*wifi_metadata) + skb->len); ++ dev_kfree_skb_any(skb); ++ break; ++ default: ++ dev_kfree_skb_any(skb); ++ } ++ ++ return; ++ } ++ ++ ath11k_nss_deliver_rx(arvif->vif, skb, true, 0, napi); ++} ++ ++static void ++ath11k_nss_mesh_obj_ext_data_callback(struct net_device *dev, struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ struct ath11k_vif *arvif; ++ struct ath11k_base *ab; ++ struct nss_wifi_mesh_encap_ext_pkt_metadata *wifi_metadata = NULL; ++ int metadata_len; ++ ++ arvif = ath11k_nss_get_arvif_from_dev(dev); ++ if (!arvif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ ab = arvif->ar->ab; ++ ++ skb->dev = dev; ++ ++ metadata_len = NSS_WIFI_MESH_ENCAP_METADATA_OFFSET_TYPE + ++ sizeof(struct nss_wifi_mesh_encap_ext_pkt_metadata); ++ ++ /* msdu from nss should contain metadata in headroom ++ * any msdu which has invalid or not contains metadata ++ * will be treated as invalid msdu and dropping it. ++ */ ++ if (!(metadata_len < skb_headroom(skb))) { ++ ath11k_warn(ab, "msdu from nss is having invalid headroom %d\n", skb_headroom(skb)); ++ dev_kfree_skb_any(skb); ++ return; ++ } ++ ++ dma_unmap_single(ab->dev, virt_to_phys(skb->head), ++ metadata_len, ++ DMA_FROM_DEVICE); ++ ++ wifi_metadata = (struct nss_wifi_mesh_encap_ext_pkt_metadata *)(skb->head + ++ NSS_WIFI_MESH_ENCAP_METADATA_OFFSET_TYPE); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, "msdu from nss ext_data _cb on mesh obj vdev"); ++ ++ switch (wifi_metadata->pkt_type) { ++ case NSS_WIFI_MESH_ENCAP_EXT_DATA_PKT_TYPE_MPATH_NOT_FOUND_EXC: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "msdu from nss ext_data for mpath not found : ", ++ skb->data, skb->len); ++ skb->protocol = eth_type_trans(skb, dev); ++ skb_reset_network_header(skb); ++ dev_queue_xmit(skb); ++ break; ++ default: ++ ath11k_warn(ab, "unknown packet type received in mesh obj ext data %d", ++ wifi_metadata->pkt_type); ++ dev_kfree_skb_any(skb); ++ } ++} ++ ++static void ++ath11k_nss_mesh_link_vdev_data_receive(struct net_device *dev, ++ struct sk_buff *skb, ++ struct napi_struct *napi) ++{ ++ struct ieee80211_vif *vif; ++ struct ath11k_vif *arvif; ++ struct ath11k_base *ab; ++ struct wireless_dev *wdev = (struct wireless_dev *)dev; ++ + vif = wdev_to_ieee80211_vif(wdev); + if (!vif) { + dev_kfree_skb_any(skb); +@@ -906,23 +1941,81 @@ ath11k_nss_ext_vdev_data_receive(struct + } + + ab = arvif->ar->ab; ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "msdu from nss data_receive_cb on mesh link vdev: ", ++ skb->data, skb->len); ++ /* data callback for mesh link vap is not expected */ ++ dev_kfree_skb_any(skb); ++} + +- skb->dev = dev; ++static void ++ath11k_nss_mesh_link_vdev_special_data_receive(struct net_device *dev, ++ struct sk_buff *skb, ++ __attribute__((unused)) struct napi_struct *napi) ++{ ++ struct ieee80211_vif *vif; ++ struct ath11k_base *ab; ++ struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL; ++ struct ath11k_skb_rxcb *rxcb; ++ struct ath11k_vif *arvif; ++ struct wireless_dev *wdev = (struct wireless_dev *)dev; + +- /* log the original skb received from nss */ +- ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", "dp rx msdu from nss ext : ", +- skb->data, skb->len); ++ vif = wdev_to_ieee80211_vif(wdev); ++ if (!vif) { ++ dev_kfree_skb_any(skb); ++ return; ++ } + +- ret = ath11k_nss_undecap(arvif, skb, &data_offs, ð_decap); +- if (ret) { +- ath11k_warn(ab, "error in nss ext rx undecap, type %d err %d\n", +- arvif->nss.decap, ret); ++ arvif = (struct ath11k_vif *)vif->drv_priv; ++ if (!arvif) { + dev_kfree_skb_any(skb); + return; + } + +- ath11k_nss_deliver_rx(arvif->vif, skb, eth_decap, data_offs, napi); ++ ab = arvif->ar->ab; ++ ++ wifi_metadata = (struct nss_wifi_vdev_per_packet_metadata *)(skb->head + ++ NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, ++ "dp special data from nss on mesh link vap: pkt_type %d\n", ++ wifi_metadata->pkt_type); ++ ++ switch (wifi_metadata->pkt_type) { ++ case NSS_WIFI_VDEV_MESH_EXT_DATA_PKT_TYPE_RX_SPL_PACKET: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "special packet meta data from nss on mesh link vdev: ", ++ wifi_metadata, ++ sizeof(struct nss_wifi_vdev_per_packet_metadata)); ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "special packet payload from nss on mesh link vdev: ", ++ skb->data, skb->len); ++ dev_kfree_skb_any(skb); ++ break; ++ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MCBC_RX: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "mcast packet exception from nss on mesh link vdev: ", ++ skb->data, skb->len); ++ rxcb = ATH11K_SKB_RXCB(skb); ++ rxcb->rx_desc = (struct hal_rx_desc *)skb->head; ++ rxcb->is_first_msdu = rxcb->is_last_msdu = true; ++ rxcb->is_continuation = false; ++ rxcb->is_mcbc = true; ++ ath11k_dp_rx_from_nss(arvif->ar, skb, napi); ++ break; ++ case NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MESH: ++ ath11k_dbg_dump(ab, ATH11K_DBG_DP_RX, "", ++ "static exception path from nss on mesh link vdev: ", ++ skb->data, skb->len); ++ dev_kfree_skb_any(skb); ++ break; ++ default: ++ ath11k_warn(ab, "unknown packet type received in mesh link vdev %d", ++ wifi_metadata->pkt_type); ++ dev_kfree_skb_any(skb); ++ break; ++ } + } ++#endif + + int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) + { +@@ -930,8 +2023,9 @@ int ath11k_nss_tx(struct ath11k_vif *arv + nss_tx_status_t status; + int encap_type = ath11k_dp_tx_get_encap_type(arvif, skb); + struct ath11k_soc_dp_stats *soc_stats = &ar->ab->soc_stats; ++ char dump_msg[100] = {0}; + +- if (encap_type != arvif->nss.encap) { ++ if (!arvif->ar->ab->nss.debug_mode && encap_type != arvif->nss.encap) { + ath11k_warn(ar->ab, "encap mismatch in nss tx skb encap type %d" \ + " vif encap type %d\n", encap_type, arvif->nss.encap); + goto drop; +@@ -946,16 +2040,45 @@ int ath11k_nss_tx(struct ath11k_vif *arv + ath11k_nss_tx_encap_nwifi(skb); + + send: +- ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, +- arvif->vif->type == NL80211_IFTYPE_AP_VLAN ? "ext vdev" : "", +- "nss tx msdu: ", skb->data, skb->len); +- +- if (arvif->vif->type == NL80211_IFTYPE_AP_VLAN) ++ if (arvif->vif->type == NL80211_IFTYPE_AP_VLAN) { ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "ext vdev", ++ "nss tx msdu: ", skb->data, skb->len); + status = nss_wifi_ext_vdev_tx_buf(arvif->nss.ctx, skb, + arvif->nss.if_num); +- else +- status = nss_wifi_vdev_tx_buf(arvif->ar->nss.ctx, skb, +- arvif->nss.if_num); ++ } else { ++ if (arvif->ar->ab->nss.debug_mode) { ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ if (encap_type == HAL_TCL_ENCAP_TYPE_ETHERNET && ++ !is_multicast_ether_addr(skb->data)) { ++ snprintf(dump_msg, sizeof(dump_msg), ++ "nss tx ucast msdu: %d ", ++ arvif->nss.mesh_handle); ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "mesh", ++ dump_msg, skb->data, skb->len); ++ status = (nss_tx_status_t)nss_wifi_meshmgr_tx_buf(arvif->nss.mesh_handle, ++ skb); ++ } else { ++#endif ++ snprintf(dump_msg, sizeof(dump_msg), ++ "nss tx mcast msdu: %d ", ++ arvif->nss.if_num); ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "mesh", ++ dump_msg, skb->data, skb->len); ++ status = nss_wifi_vdev_tx_buf(arvif->ar->nss.ctx, skb, ++ arvif->nss.if_num); ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ } ++#endif ++ } else { ++ snprintf(dump_msg, sizeof(dump_msg), ++ "nss tx msdu: %d ", ++ arvif->nss.if_num); ++ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_TX, "", ++ dump_msg, skb->data, skb->len); ++ status = nss_wifi_vdev_tx_buf(arvif->ar->nss.ctx, skb, ++ arvif->nss.if_num); ++ } ++ } + + if (status != NSS_TX_SUCCESS) { + ath11k_dbg(ar->ab, (ATH11K_DBG_NSS | ATH11K_DBG_DP_TX), +@@ -1057,6 +2180,9 @@ static int ath11k_nss_vdev_configure(str + + vdev_cfg = &vdev_msg->msg.vdev_config; + ++ if (arvif->vif->type == NL80211_IFTYPE_MESH_POINT) ++ vdev_cfg->vap_ext_mode = WIFI_VDEV_EXT_MODE_MESH_LINK; ++ + vdev_cfg->radio_ifnum = ar->nss.if_num; + vdev_cfg->vdev_id = arvif->vdev_id; + +@@ -1095,6 +2221,39 @@ free: + return ret; + } + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static int ath11k_nss_mesh_obj_assoc_link_vap(struct ath11k_vif *arvif) ++{ ++ struct nss_wifi_mesh_assoc_link_vap *msg; ++ struct ath11k_base *ab = arvif->ar->ab; ++ nss_tx_status_t status; ++ int ret; ++ ++ msg = kzalloc(sizeof(struct nss_wifi_mesh_assoc_link_vap), GFP_ATOMIC); ++ if (!msg) ++ return -ENOMEM; ++ ++ msg->link_vap_id = arvif->nss.if_num; ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, "nss mesh assoc link vap %d, mesh handle %d\n", ++ arvif->nss.if_num, arvif->nss.mesh_handle); ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_assoc_link_vap_sync(arvif->nss.mesh_handle, msg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failed mesh obj vdev tx msg for assoc link vap nss_err:%d\n", ++ status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = 0; ++free: ++ kfree(msg); ++ ++ return ret; ++} ++#endif ++ + static void ath11k_nss_vdev_unregister(struct ath11k_vif *arvif) + { + struct ath11k_base *ab = arvif->ar->ab; +@@ -1106,6 +2265,14 @@ static void ath11k_nss_vdev_unregister(s + ath11k_dbg(ab, ATH11K_DBG_NSS, "unregistered nss vdev %d \n", + arvif->nss.if_num); + break; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ case NL80211_IFTYPE_MESH_POINT: ++ nss_unregister_wifi_vdev_if(arvif->nss.if_num); ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "unregistered nss mesh vdevs mesh link %d\n", ++ arvif->nss.if_num); ++ break; ++#endif + default: + ath11k_warn(ab, "unsupported interface type %d for nss vdev unregister\n", + arvif->vif->type); +@@ -1113,6 +2280,78 @@ static void ath11k_nss_vdev_unregister(s + } + } + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static int ath11k_nss_mesh_alloc_register(struct ath11k_vif *arvif, ++ struct net_device *netdev) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct nss_wifi_mesh_config_msg *nss_msg; ++ struct arvif_nss *nss = &arvif->nss; ++ int ret = 0; ++ ++ nss->mesh_ttl = ATH11K_MESH_DEFAULT_ELEMENT_TTL; ++ nss->mpath_refresh_time = 1000; /* msecs */ ++ nss->mesh_forward_enabled = true; ++ ++ nss_msg = kzalloc(sizeof(*nss_msg), GFP_KERNEL); ++ if (!nss_msg) ++ return -ENOMEM; ++ ++ nss_msg->ttl = nss->mesh_ttl; ++ nss_msg->mesh_path_refresh_time = nss->mpath_refresh_time; ++ nss_msg->mpp_learning_mode = mpp_mode; ++ nss_msg->block_mesh_forwarding = 0; ++ ether_addr_copy(nss_msg->local_mac_addr, arvif->vif->addr); ++ nss_msg->config_flags = ++ NSS_WIFI_MESH_CONFIG_FLAG_TTL_VALID | ++ NSS_WIFI_MESH_CONFIG_FLAG_MPATH_REFRESH_VALID | ++ NSS_WIFI_MESH_CONFIG_FLAG_MPP_LEARNING_MODE_VALID | ++ NSS_WIFI_MESH_CONFIG_FLAG_BLOCK_MESH_FWD_VALID | ++ NSS_WIFI_MESH_CONFIG_FLAG_LOCAL_MAC_VALID; ++ ++ arvif->nss.mesh_handle = nss_wifi_meshmgr_if_create_sync(netdev, nss_msg, ++ ath11k_nss_mesh_obj_vdev_data_receive, ++ ath11k_nss_mesh_obj_ext_data_callback, ++ ath11k_nss_mesh_obj_vdev_event_receive); ++ if (arvif->nss.mesh_handle == NSS_WIFI_MESH_HANDLE_INVALID) { ++ ath11k_warn(ab, "failed to create meshmgr\n"); ++ ret = -EINVAL; ++ } ++ ++ kfree(nss_msg); ++ ++ return ret; ++} ++ ++static int ath11k_nss_mesh_vdev_register(struct ath11k_vif *arvif, ++ struct net_device *netdev) ++{ ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_base *ab = ar->ab; ++ nss_tx_status_t status; ++ u32 features = 0; ++ ++ status = nss_register_wifi_vdev_if(ar->nss.ctx, ++ arvif->nss.if_num, ++ ath11k_nss_mesh_link_vdev_data_receive, ++ ath11k_nss_mesh_link_vdev_special_data_receive, ++ ath11k_nss_vdev_event_receive, ++ (struct net_device *)netdev->ieee80211_ptr, ++ features); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "failed to register nss mesh link vdev if_num %d nss_err:%d\n", ++ arvif->nss.if_num, status); ++ nss_unregister_wifi_vdev_if(arvif->nss.if_num); ++ return -EINVAL; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS, "registered nss mesh link vdev if_num %d\n", ++ arvif->nss.if_num); ++ ++ return 0; ++} ++#endif ++ + static int ath11k_nss_vdev_register(struct ath11k_vif *arvif, + struct net_device *netdev) + { +@@ -1140,6 +2379,15 @@ static int ath11k_nss_vdev_register(stru + arvif->nss.if_num); + + break; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ case NL80211_IFTYPE_MESH_POINT: ++ if (!ab->nss.mesh_nss_offload_enabled) ++ return -ENOTSUPP; ++ ++ if (ath11k_nss_mesh_vdev_register(arvif, netdev)) ++ return -EINVAL; ++ break; ++#endif + default: + ath11k_warn(ab, "unsupported interface type %d for nss vdev register\n", + arvif->vif->type); +@@ -1149,6 +2397,62 @@ static int ath11k_nss_vdev_register(stru + return 0; + } + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static void ath11k_nss_mesh_vdev_free(struct ath11k_vif *arvif) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct ath11k *ar = arvif->ar; ++ struct ath11k_nss_mpath_entry *mpath_entry, *mpath_tmp; ++ struct ath11k_nss_mpp_entry *mpp_entry, *mpp_tmp; ++ struct arvif_nss *nss = &arvif->nss, *nss_entry, *nss_tmp; ++ LIST_HEAD(mpath_local_entry); ++ LIST_HEAD(mpp_local_entry); ++ nss_tx_status_t status; ++ ++ del_timer_sync(&nss->mpp_expiry_timer); ++ ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&nss->mpath_dump, &mpath_local_entry); ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(mpath_entry, mpath_tmp, &mpath_local_entry, list) { ++ list_del(&mpath_entry->list); ++ kfree(mpath_entry); ++ } ++ ++ spin_lock_bh(&ar->nss.dump_lock); ++ list_splice_tail_init(&nss->mpp_dump, &mpp_local_entry); ++ spin_unlock_bh(&ar->nss.dump_lock); ++ ++ list_for_each_entry_safe(mpp_entry, mpp_tmp, &mpp_local_entry, list) { ++ list_del(&mpp_entry->list); ++ kfree(mpp_entry); ++ } ++ ++ list_for_each_entry_safe(nss_entry, nss_tmp, &mesh_vaps, list) ++ list_del(&nss_entry->list); ++ ++ status = nss_dynamic_interface_dealloc_node( ++ arvif->nss.if_num, ++ NSS_DYNAMIC_INTERFACE_TYPE_VAP); ++ if (status != NSS_TX_SUCCESS) ++ ath11k_warn(ab, "failed to free nss mesh link vdev nss_err:%d\n", ++ status); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss mesh link vdev interface deallocated\n"); ++ ++ status = (nss_tx_status_t)nss_wifi_meshmgr_if_destroy_sync(arvif->nss.mesh_handle); ++ ++ if (status != NSS_TX_SUCCESS) ++ ath11k_warn(ab, "failed to free nss mesh object vdev nss_err:%d\n", ++ status); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_NSS, ++ "nss mesh object vdev interface deallocated\n"); ++} ++#endif ++ + void ath11k_nss_vdev_free(struct ath11k_vif *arvif) + { + struct ath11k_base *ab = arvif->ar->ab; +@@ -1168,6 +2472,11 @@ void ath11k_nss_vdev_free(struct ath11k_ + "nss vdev interface deallocated\n"); + + return; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ case NL80211_IFTYPE_MESH_POINT: ++ ath11k_nss_mesh_vdev_free(arvif); ++ return; ++#endif + default: + ath11k_warn(ab, "unsupported interface type %d for nss vdev dealloc\n", + arvif->vif->type); +@@ -1175,11 +2484,96 @@ void ath11k_nss_vdev_free(struct ath11k_ + } + } + +-static int ath11k_nss_vdev_alloc(struct ath11k_vif *arvif) ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++struct arvif_nss *ath11k_nss_find_arvif_by_if_num(int if_num) ++{ ++ struct arvif_nss *nss; ++ ++ list_for_each_entry(nss, &mesh_vaps, list) { ++ if (if_num == nss->if_num) ++ return nss; ++ } ++ return NULL; ++} ++ ++int ath11k_nss_assoc_link_arvif_to_ifnum(struct ath11k_vif *arvif, int if_num) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ struct ath11k_vif *arvif_link; ++ struct wireless_dev *wdev; ++ struct arvif_nss *nss; ++ int ret; ++ ++ wdev = ieee80211_vif_to_wdev_relaxed(arvif->vif); ++ if (!wdev) { ++ ath11k_warn(ab, "ath11k_nss: wdev is null\n"); ++ return -EINVAL; ++ } ++ ++ if (!wdev->netdev) { ++ ath11k_warn(ab, "ath11k_nss: netdev is null\n"); ++ return -EINVAL; ++ } ++ ++ nss = ath11k_nss_find_arvif_by_if_num(if_num); ++ if (!nss) { ++ ath11k_warn(ab, "ath11k_nss: unable to find if_num %d\n",if_num); ++ return -EINVAL; ++ } ++ ++ arvif_link = container_of(nss, struct ath11k_vif, nss); ++ ++ ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, ++ "assoc link vap ifnum %d to mesh handle of link id %d\n", ++ arvif_link->nss.if_num, arvif->nss.if_num); ++ ++ arvif_link->nss.mesh_handle = arvif->nss.mesh_handle; ++ ++ ret = ath11k_nss_mesh_obj_assoc_link_vap(arvif_link); ++ if (ret) ++ ath11k_warn(ab, "failed to associate link vap to mesh vap %d\n", ret); ++ ++ return 0; ++} ++ ++static int ath11k_nss_mesh_vdev_alloc(struct ath11k_vif *arvif, ++ struct net_device *netdev) ++{ ++ struct ath11k_base *ab = arvif->ar->ab; ++ int if_num; ++ ++ if (!ab->nss.mesh_nss_offload_enabled) ++ return -ENOTSUPP; ++ ++ if_num = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_VAP); ++ if (if_num < 0) { ++ ath11k_warn(ab, "failed to allocate nss mesh link vdev\n"); ++ return -EINVAL; ++ } ++ ++ arvif->nss.if_num = if_num; ++ ++ INIT_LIST_HEAD(&arvif->nss.list); ++ list_add_tail(&arvif->nss.list, &mesh_vaps); ++ ++ INIT_LIST_HEAD(&arvif->nss.mpath_dump); ++ init_completion(&arvif->nss.dump_mpath_complete); ++ INIT_LIST_HEAD(&arvif->nss.mpp_dump); ++ init_completion(&arvif->nss.dump_mpp_complete); ++ ++ return 0; ++} ++#endif ++ ++static int ath11k_nss_vdev_alloc(struct ath11k_vif *arvif, ++ struct net_device *netdev) + { + struct ath11k_base *ab = arvif->ar->ab; + enum nss_dynamic_interface_type if_type; + int if_num; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ int ret; ++#endif + + /* Initialize completion for verifying NSS message response */ + init_completion(&arvif->nss.complete); +@@ -1201,6 +2595,16 @@ static int ath11k_nss_vdev_alloc(struct + arvif->nss.if_num); + + break; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ case NL80211_IFTYPE_MESH_POINT: ++ ret = ath11k_nss_mesh_vdev_alloc(arvif, netdev); ++ if (ret) { ++ ath11k_warn(ab, "failed to allocate nss vdev of mesh type %d\n", ++ ret); ++ return ret; ++ } ++ break; ++#endif + default: + ath11k_warn(ab, "unsupported interface type %d for nss vdev alloc\n", + arvif->vif->type); +@@ -1238,7 +2642,7 @@ int ath11k_nss_vdev_create(struct ath11k + return -EINVAL; + } + +- ret = ath11k_nss_vdev_alloc(arvif); ++ ret = ath11k_nss_vdev_alloc(arvif, wdev->netdev); + if (ret) + return ret; + +@@ -1254,6 +2658,45 @@ int ath11k_nss_vdev_create(struct ath11k + goto unregister_vdev; + + break; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ case NL80211_IFTYPE_MESH_POINT: ++ ret = ath11k_nss_mesh_alloc_register(arvif, wdev->netdev); ++ if (ret) { ++ ath11k_warn(ab, "failed to alloc and register mesh vap %d\n", ret); ++ goto unregister_vdev; ++ } ++ ++ ret = ath11k_nss_vdev_configure(arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to configure nss mesh link vdev\n"); ++ goto unregister_vdev; ++ } ++ ++ ret = ath11k_nss_mesh_obj_assoc_link_vap(arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to associate link vap to mesh vap %d\n", ret); ++ goto unregister_vdev; ++ } ++ ++ ret = ath11k_nss_vdev_set_cmd(arvif, ++ ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD, 1); ++ if (ret) { ++ ath11k_warn(ab, "failed to enable mcast/bcast exception %d\n", ret); ++ goto unregister_vdev; ++ } ++ ++ ath11k_debugfs_nss_mesh_vap_create(arvif); ++ ++ /* This timer cb is called at specified ++ * interval to update mpp exp timeout */ ++ timer_setup(&arvif->nss.mpp_expiry_timer, ++ ath11k_nss_mpp_timer_cb, 0); ++ ++ /* Start the initial timer in 2 secs */ ++ mod_timer(&arvif->nss.mpp_expiry_timer, ++ jiffies + msecs_to_jiffies(2 * HZ)); ++ break; ++#endif + default: + ret = -ENOTSUPP; + goto unregister_vdev; +@@ -1310,6 +2753,15 @@ int ath11k_nss_vdev_up(struct ath11k_vif + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) + return 0; + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ if (arvif->vif->type == NL80211_IFTYPE_MESH_POINT) { ++ status = (nss_tx_status_t)nss_wifi_meshmgr_if_up(arvif->nss.mesh_handle); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss mesh vdev up error %d\n", status); ++ return -EINVAL; ++ } ++ } ++#endif + vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); + if (!vdev_msg) + return -ENOMEM; +@@ -1357,6 +2809,15 @@ int ath11k_nss_vdev_down(struct ath11k_v + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) + return 0; + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ if (arvif->vif->type == NL80211_IFTYPE_MESH_POINT) { ++ status = (nss_tx_status_t)nss_wifi_meshmgr_if_down(arvif->nss.mesh_handle); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ar->ab, "nss mesh vdev up error %d\n", status); ++ return -EINVAL; ++ } ++ } ++#endif + vdev_msg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_ATOMIC); + if (!vdev_msg) + return -ENOMEM; +@@ -2731,6 +4192,51 @@ static int ath11k_nss_get_dynamic_interf + } + } + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static int ath11k_nss_mesh_capability(struct ath11k_base *ab) ++{ ++ struct nss_wifili_msg *wlmsg = NULL; ++ nss_wifili_msg_callback_t msg_cb; ++ nss_tx_status_t status; ++ int ret = 0; ++ ++ wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); ++ if (!wlmsg) ++ return -ENOMEM; ++ ++ msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; ++ ++ reinit_completion(&ab->nss.complete); ++ ++ nss_cmn_msg_init(&wlmsg->cm, ab->nss.if_num, ++ NSS_WIFILI_SEND_MESH_CAPABILITY_INFO, ++ sizeof(struct nss_wifili_mesh_capability_info), ++ msg_cb, NULL); ++ ++ status = nss_wifili_tx_msg(ab->nss.ctx, wlmsg); ++ if (status != NSS_TX_SUCCESS) { ++ ath11k_warn(ab, "nss failed to get mesh capability msg %d\n", status); ++ ret = -EINVAL; ++ goto free; ++ } ++ ++ ret = wait_for_completion_timeout(&ab->nss.complete, ++ msecs_to_jiffies(ATH11K_NSS_MSG_TIMEOUT_MS)); ++ if (!ret) { ++ ath11k_warn(ab, "timeout while waiting for mesh capability check\n"); ++ ret = -ETIMEDOUT; ++ goto free; ++ } ++ ++ kfree(wlmsg); ++ return 0; ++ ++free: ++ kfree(wlmsg); ++ return ret; ++} ++#endif ++ + static int ath11k_nss_init(struct ath11k_base *ab) + { + struct nss_wifili_init_msg *wim = NULL; +@@ -2863,6 +4369,17 @@ static int ath11k_nss_init(struct ath11k + + kfree(wlmsg); + ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ /* Create a mesh links read debugfs entry */ ++ ath11k_debugfs_nss_soc_create(ab); ++ ++ /* Check for mesh capability */ ++ ret = ath11k_nss_mesh_capability(ab); ++ ++ if (ret) ++ ath11k_err(ab, "Mesh offload is not enabled %d\n", ret); ++#endif ++ + ath11k_dbg(ab, ATH11K_DBG_NSS, "NSS Init Message TX Success %p %d\n", + ab->nss.ctx, ab->nss.if_num); + return 0; +--- a/drivers/net/wireless/ath/ath11k/nss.h ++++ b/drivers/net/wireless/ath/ath11k/nss.h +@@ -10,8 +10,12 @@ + #ifdef CPTCFG_ATH11K_NSS_SUPPORT + #include + #include +- ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++#include ++#endif + #endif ++#include "../../../../../net/mac80211/mesh.h" ++ + struct ath11k; + struct ath11k_base; + struct ath11k_vif; +@@ -23,8 +27,9 @@ struct hal_rx_user_status; + + /* NSS DBG macro is not included as part of debug enum to avoid + * frequent changes during upgrade*/ +-#define ATH11K_DBG_NSS 0x40000000 +-#define ATH11K_DBG_NSS_WDS 0x80000000 ++#define ATH11K_DBG_NSS 0x20000000 ++#define ATH11K_DBG_NSS_WDS 0x40000000 ++#define ATH11K_DBG_NSS_MESH 0x80000000 + + /* WIFILI Supported Target Types */ + #define ATH11K_WIFILI_TARGET_TYPE_UNKNOWN 0xFF +@@ -60,6 +65,7 @@ struct hal_rx_user_status; + /* Timeout for waiting for response from NSS on TX msg */ + #define ATH11K_NSS_MSG_TIMEOUT_MS 5000 + ++#define ATH11K_MESH_DEFAULT_ELEMENT_TTL 31 + /* Init Flags */ + #define WIFILI_NSS_CCE_DISABLED 0x1 + #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 +@@ -119,6 +125,8 @@ enum ath11k_nss_opmode { + ATH11K_NSS_OPMODE_MONITOR, + }; + ++#define ATH11K_MPP_EXPIRY_TIMER_INTERVAL_MS 60 * HZ ++ + struct peer_stats { + u64 last_rx; + u64 last_ack; +@@ -158,10 +166,30 @@ struct ath11k_nss_peer { + struct completion complete; + }; + ++struct ath11k_nss_mpath_entry { ++ struct list_head list; ++ u32 num_entries; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ struct nss_wifi_mesh_path_dump_entry mpath[0]; ++#endif ++}; ++ ++struct ath11k_nss_mpp_entry { ++ struct list_head list; ++ u32 num_entries; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ struct nss_wifi_mesh_proxy_path_dump_entry mpp[0]; ++#endif ++}; ++ + /* Structure to hold the vif related info for nss offload support */ + struct arvif_nss { + /* dynamic ifnum allocated by nss driver for vif */ + int if_num; ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++ /* mesh handle for mesh obj vap */ ++ nss_wifi_mesh_handle_t mesh_handle; ++#endif + /* Used for completion status for vdev config nss messages */ + struct completion complete; + /* Keep the copy of encap type for nss */ +@@ -183,6 +211,25 @@ struct arvif_nss { + /* WDS cfg should be done only once for ext vdev */ + bool wds_cfg_done; + bool created; ++ ++ bool mpp_aging; ++ bool mpp_dump_req; ++ struct timer_list mpp_expiry_timer; ++ u8 mesh_ttl; ++ bool mesh_forward_enabled; ++ u32 metadata_type; ++ u32 mpath_refresh_time; ++ ++ struct list_head list; ++ struct list_head mpath_dump; ++ /* total number of mpath entries in all of the mpath_dump list */ ++ u32 mpath_dump_num_entries; ++ struct completion dump_mpath_complete; ++ ++ struct list_head mpp_dump; ++ /* total number of mpp entries in all of the mpp_dump list */ ++ u32 mpp_dump_num_entries; ++ struct completion dump_mpp_complete; + }; + + /* Structure to hold the pdev/radio related info for nss offload support */ +@@ -191,6 +238,8 @@ struct ath11k_nss { + int if_num; + /* Radio/pdev Context obtained on pdev register */ + void* ctx; ++ /* protects stats from nss */ ++ spinlock_t dump_lock; + }; + + /* Structure to hold the soc related info for nss offload support */ +@@ -199,6 +248,8 @@ struct ath11k_soc_nss { + bool enabled; + /* turn on/off nss stats support in ath11k */ + bool stats_enabled; ++ /* Mesh offload support as advertised by nss */ ++ bool mesh_nss_offload_enabled; + /* soc nss ctx */ + void* ctx; + /* if_num to be used for soc related nss messages */ +@@ -261,6 +312,29 @@ void ath11k_nss_update_sta_rxrate(struct + int ath11k_nss_setup(struct ath11k_base *ab); + int ath11k_nss_teardown(struct ath11k_base *ab); + void ath11k_nss_ext_rx_stats(struct ath11k_base *ab, struct htt_rx_ring_tlv_filter *tlv_filter); ++int ath11k_nss_dump_mpath_request(struct ath11k_vif *arvif); ++int ath11k_nss_dump_mpp_request(struct ath11k_vif *arvif); ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++int ath11k_nss_mesh_config_path(struct ath11k *ar, struct ath11k_vif *arvif, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path); ++#else ++static inline int ++ath11k_nss_mesh_config_path(struct ath11k *ar, struct ath11k_vif *arvif, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ return 0; ++} ++#endif ++int ath11k_nss_mesh_config_update(struct ieee80211_vif *vif, int changed); ++int ath11k_nss_assoc_link_arvif_to_ifnum(struct ath11k_vif *arvif, int if_num); ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++int ath11k_nss_mesh_exception_flags(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_exception_flag_msg *nss_msg); ++int ath11k_nss_exc_rate_config(struct ath11k_vif *arvif, ++ struct nss_wifi_mesh_rate_limit_config *nss_exc_cfg); ++#endif + #else + static inline int ath11k_nss_tx(struct ath11k_vif *arvif, struct sk_buff *skb) + { +@@ -431,5 +505,38 @@ static inline void ath11k_nss_ext_rx_sta + { + return; + } ++ ++#ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT ++static inline int ++ath11k_nss_mesh_config_path(struct ath11k *ar, struct ath11k_vif *arvif, ++ enum ieee80211_mesh_path_offld_cmd cmd, ++ struct ieee80211_mesh_path_offld *path) ++{ ++ return 0; ++} ++#endif ++static inline int ++ath11k_nss_mesh_config_update(struct ieee80211_vif *vif, int changed) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_assoc_link_arvif_to_ifnum(struct ath11k_vif *arvif, ++ int if_num) ++{ ++ return 0; ++} ++ ++static inline int ath11k_nss_mesh_exception_flags(struct ath11k_vif *arvif, ++ void *nss_msg) ++{ ++ return 0; ++} ++ ++static inline int ++ath11k_nss_exc_rate_config(struct ath11k_vif *arvif, void *nss_exc_cfg) ++{ ++ return 0; ++} + #endif /* CPTCFG_ATH11K_NSS_SUPPORT */ + #endif +--- a/drivers/net/wireless/ath/ath11k/debug.h ++++ b/drivers/net/wireless/ath/ath11k/debug.h +@@ -10,6 +10,7 @@ + #include "trace.h" + #include "debugfs.h" + ++extern struct dentry *debugfs_ath11k; + enum ath11k_debug_mask { + ATH11K_DBG_AHB = 0x00000001, + ATH11K_DBG_WMI = 0x00000002, +--- a/local-symbols ++++ b/local-symbols +@@ -171,6 +171,7 @@ ATH11K= + ATH11K_AHB= + ATH11K_PCI= + ATH11K_NSS_SUPPORT= ++ATH11K_NSS_MESH_SUPPORT= + ATH11K_MEM_PROFILE_256M= + ATH11K_MEM_PROFILE_512M= + ATH11K_DEBUG= +--- a/drivers/net/wireless/ath/ath11k/Kconfig ++++ b/drivers/net/wireless/ath/ath11k/Kconfig +@@ -23,6 +23,15 @@ config ATH11K_NSS_SUPPORT + + If unsure, say Y to enable NSS offload support. + ++config ATH11K_NSS_MESH_SUPPORT ++ bool "QCA ath11k nss mesh support" ++ depends on ATH11K_NSS_SUPPORT ++ default n ++ ---help--- ++ Enables NSS offload support for ATH11K Mesh ++ ++ If unsure, say Y to enable NSS offload support. ++ + config ATH11K_MEM_PROFILE_512M + bool "ath11k enable 512MB memory profile" + depends on ATH11K diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch b/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch similarity index 70% rename from package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch rename to package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch index 47c6b7ec3e..2fa70d0f39 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-301-ath11k-nss-mcbc-exception.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/301-ath11k-nss-mcbc-exception.patch @@ -16,7 +16,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -611,7 +611,7 @@ static int ath11k_nss_undecap_nwifi(stru +@@ -606,7 +606,7 @@ static int ath11k_nss_undecap_nwifi(stru static void ath11k_nss_wds_type_rx(struct ath11k *ar, struct net_device *dev, u8* src_mac, u8 is_sa_valid, u8 addr4_valid, @@ -25,7 +25,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 { struct ath11k_base *ab = ar->ab; struct ath11k_ast_entry *ast_entry = NULL; -@@ -647,8 +647,6 @@ static void ath11k_nss_wds_type_rx(struc +@@ -642,8 +642,6 @@ static void ath11k_nss_wds_type_rx(struc } } @@ -34,7 +34,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } spin_unlock_bh(&ab->base_lock); -@@ -692,8 +690,7 @@ static void ath11k_nss_mec_handler(struc +@@ -687,8 +685,7 @@ static void ath11k_nss_mec_handler(struc static void ath11k_nss_vdev_spl_receive_ext_wdsdata(struct ath11k_vif *arvif, struct sk_buff *skb, @@ -44,7 +44,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 { struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; -@@ -715,7 +712,7 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -710,7 +707,7 @@ static void ath11k_nss_vdev_spl_receive_ switch (wds_type) { case NSS_WIFI_VDEV_WDS_TYPE_RX: ath11k_nss_wds_type_rx(ar, skb->dev, src_mac, is_sa_valid, @@ -53,25 +53,21 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: ath11k_nss_mec_handler(ar, (u8 *)(skb->data)); -@@ -778,14 +775,16 @@ ath11k_nss_vdev_special_data_receive(str - { - struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL; +@@ -775,10 +772,12 @@ ath11k_nss_vdev_special_data_receive(str struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL; -+ struct nss_wifi_vdev_addr4_data_metadata *addr4_metadata = NULL; - struct wireless_dev *wdev; - struct ieee80211_vif *vif; struct ath11k_vif *arvif; struct ath11k_base *ab; - bool drop = false; -+ struct ath11k_skb_rxcb *rxcb; bool eth_decap = false; int data_offs = 0; int ret = 0; ++ struct nss_wifi_vdev_addr4_data_metadata *addr4_metadata = NULL; ++ struct ath11k_skb_rxcb *rxcb; + struct ath11k_peer *ta_peer = NULL; arvif = ath11k_nss_get_arvif_from_dev(dev); if (!arvif) { -@@ -843,15 +842,50 @@ ath11k_nss_vdev_special_data_receive(str +@@ -810,15 +809,50 @@ ath11k_nss_vdev_special_data_receive(str return; } @@ -130,7 +126,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 } static void -@@ -1049,6 +1083,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 +@@ -2129,6 +2163,9 @@ int ath11k_nss_vdev_set_cmd(struct ath11 case ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD: cmd = NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD; break; @@ -140,7 +136,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 default: return -EINVAL; } -@@ -1299,12 +1336,31 @@ int ath11k_nss_vdev_create(struct ath11k +@@ -2651,12 +2688,31 @@ int ath11k_nss_vdev_create(struct ath11k goto free_vdev; switch (arvif->vif->type) { @@ -171,18 +167,9 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 + goto unregister_vdev; + } break; - default: - ret = -ENOTSUPP; -@@ -1463,7 +1519,7 @@ int ath11k_nss_ext_vdev_cfg_wds_peer(str - - cfg_wds_msg = &ext_vdev_msg->msg.wmsg; - cfg_wds_msg->wds_peer_id = wds_peer_id; -- ether_addr_copy(cfg_wds_msg->mac_addr, wds_addr); -+ ether_addr_copy((u8 *) cfg_wds_msg->mac_addr, wds_addr); - - nss_wifi_ext_vdev_msg_init(ext_vdev_msg, arvif->nss.if_num, - NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS, -@@ -1587,7 +1643,6 @@ static int ath11k_nss_ext_vdev_register( + #ifdef CPTCFG_ATH11K_NSS_MESH_SUPPORT + case NL80211_IFTYPE_MESH_POINT: +@@ -2987,7 +3043,6 @@ static int ath11k_nss_ext_vdev_register( { struct ath11k *ar = arvif->ar; struct ath11k_base *ab = ar->ab; @@ -190,7 +177,7 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 u32 features = 0; if (arvif->vif->type != NL80211_IFTYPE_AP_VLAN || arvif->nss.ctx) -@@ -1601,7 +1656,7 @@ static int ath11k_nss_ext_vdev_register( +@@ -3001,7 +3056,7 @@ static int ath11k_nss_ext_vdev_register( if (!arvif->nss.ctx) { ath11k_warn(ab, "failed to register nss vdev if_num %d nss_err:%d\n", @@ -201,53 +188,16 @@ Change-Id: I4a6ac67a1c2cf3ab7a219d0953907191606a5e70 --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -110,10 +110,14 @@ enum ath11k_nss_vdev_cmd { +@@ -115,8 +115,12 @@ enum ath11k_nss_vdev_cmd { ATH11K_NSS_WIFI_VDEV_ENCAP_TYPE_CMD, ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, ATH11K_NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD, + ATH11K_NSS_WIFI_VDEV_CFG_MCBC_EXC_TO_HOST_CMD, }; - #define WIFILI_SCHEME_ID_INVALID -1 - +/* Enables the MCBC exception in NSS fw, 1 = enable */ +#define ATH11K_NSS_ENABLE_MCBC_EXC 1 + enum ath11k_nss_opmode { ATH11K_NSS_OPMODE_UNKNOWN, ATH11K_NSS_OPMODE_AP, ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3086,6 +3086,23 @@ static void ath11k_dp_rx_process_receive - } - } - -+void ath11k_dp_rx_from_nss(struct ath11k *ar, struct sk_buff *msdu, -+ struct napi_struct *napi) -+{ -+ struct ieee80211_rx_status rx_status = {0}; -+ struct ath11k_skb_rxcb *rxcb; -+ bool fast_rx = false; -+ -+ rxcb = ATH11K_SKB_RXCB(msdu); -+ -+ ath11k_dp_rx_h_ppdu(ar, rxcb->rx_desc, &rx_status); -+ ath11k_dp_rx_h_mpdu(ar, msdu, rxcb->rx_desc, &rx_status, &fast_rx); -+ -+ rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED; -+ -+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status); -+} -+ - int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id, - struct napi_struct *napi, int budget) - { ---- a/drivers/net/wireless/ath/ath11k/dp_rx.h -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.h -@@ -157,4 +157,6 @@ bool ath11k_dp_rx_h_attn_is_mcbc(struct - struct hal_rx_desc *desc); - u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, - struct hal_rx_desc *desc); -+void ath11k_dp_rx_from_nss(struct ath11k *ar, struct sk_buff *msdu, -+ struct napi_struct *napi); - #endif /* ATH11K_DP_RX_H */ diff --git a/package/kernel/mac80211/patches/nss/ath11k/314-ath11k-Fix-peer-lookup-failure-in-mgmt-tx-completion.patch b/package/kernel/mac80211/patches/nss/ath11k/314-ath11k-Fix-peer-lookup-failure-in-mgmt-tx-completion.patch new file mode 100644 index 0000000000..6edfd5f920 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/314-ath11k-Fix-peer-lookup-failure-in-mgmt-tx-completion.patch @@ -0,0 +1,125 @@ +From e58249f0a5826926c0e96acea4dfbc8683cfaaab Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Wed, 9 Jun 2021 17:32:30 +0530 +Subject: [PATCH] ath11k: Fix peer lookup failure in mgmt tx completion + +In mgmt tx completion handler, peer lookup is done using address 2 +of transmitted frame to find arvif and update mgmt tx completion stats. +For STA interface, self peer will not be created and hence +peer lookup with address 2 keeps failing. +Fix this by obtaining vif directly from SKB_CB for updating stats. + +Possible vif removal races: +1. If vif removed before tx completion all idrs associated to the vif +would've been flushed and finding msdu with idr will fail, +hence tx completion wont be processed therafter. +2. Added data lock to protect vif removal during tx completion processing. + +Signed-off-by: Rameshkumar Sundaram +--- + drivers/net/wireless/ath/ath11k/mac.c | 2 ++ + drivers/net/wireless/ath/ath11k/wmi.c | 53 ++++++++++++++++------------------- + 2 files changed, 26 insertions(+), 29 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -7638,8 +7638,10 @@ err_vdev_del: + kfree(arvif->vlan_keyid_map); + ath11k_peer_cleanup(ar, arvif->vdev_id); + ++ spin_lock_bh(&ar->data_lock); + idr_for_each(&ar->txmgmt_idr, + ath11k_mac_vif_txmgmt_idr_remove, vif); ++ spin_unlock_bh(&ar->data_lock); + + for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { + spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock); +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -5966,13 +5966,13 @@ static int wmi_process_tx_comp(struct at + struct ieee80211_tx_info *info; + struct ath11k_skb_cb *skb_cb; + struct ieee80211_hdr *hdr; +- struct ath11k_peer *peer; + struct ieee80211_vif *vif; + struct ath11k_vif *arvif; + struct ath11k_mgmt_frame_stats *mgmt_stats; + u16 frm_type; + int num_mgmt; + ++ spin_lock_bh(&ar->data_lock); + spin_lock_bh(&ar->txmgmt_idr_lock); + msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id); + +@@ -5980,6 +5980,7 @@ static int wmi_process_tx_comp(struct at + ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n", + tx_compl_param->desc_id); + spin_unlock_bh(&ar->txmgmt_idr_lock); ++ spin_unlock_bh(&ar->data_lock); + return -ENOENT; + } + +@@ -5988,6 +5989,28 @@ static int wmi_process_tx_comp(struct at + + skb_cb = ATH11K_SKB_CB(msdu); + dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); ++ hdr = (struct ieee80211_hdr *)msdu->data; ++ ++ if (ieee80211_is_mgmt(hdr->frame_control)) { ++ frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); ++ vif = skb_cb->vif; ++ ++ if (!vif) { ++ ath11k_warn(ar->ab, "failed to find vif to update txcompl mgmt stats\n"); ++ goto skip_mgmt_stats; ++ } ++ ++ arvif = ath11k_vif_to_arvif(vif); ++ mgmt_stats = &arvif->mgmt_stats; ++ ++ if (!tx_compl_param->status) ++ mgmt_stats->tx_compl_succ[frm_type]++; ++ else ++ mgmt_stats->tx_compl_fail[frm_type]++; ++ } ++ ++skip_mgmt_stats: ++ spin_unlock_bh(&ar->data_lock); + + info = IEEE80211_SKB_CB(msdu); + if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && +@@ -6003,34 +6026,6 @@ static int wmi_process_tx_comp(struct at + */ + info->status.rates[0].idx = -1; + +- hdr = (struct ieee80211_hdr *)msdu->data; +- frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); +- +- spin_lock_bh(&ar->ab->base_lock); +- peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2); +- if (!peer) { +- spin_unlock_bh(&ar->ab->base_lock); +- ath11k_warn(ar->ab, "failed to find peer to update txcompl mgmt stats\n"); +- goto skip_mgmt_stats; +- } +- +- vif = peer->vif; +- spin_unlock_bh(&ar->ab->base_lock); +- +- spin_lock_bh(&ar->data_lock); +- arvif = ath11k_vif_to_arvif(vif); +- mgmt_stats = &arvif->mgmt_stats; +- +- if (ieee80211_is_mgmt(hdr->frame_control)) { +- if (!tx_compl_param->status) +- mgmt_stats->tx_compl_succ[frm_type]++; +- else +- mgmt_stats->tx_compl_fail[frm_type]++; +- } +- +- spin_unlock_bh(&ar->data_lock); +- +-skip_mgmt_stats: + ieee80211_tx_status_irqsafe(ar->hw, msdu); + + num_mgmt = atomic_dec_if_positive(&ar->num_pending_mgmt_tx); diff --git a/package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch b/package/kernel/mac80211/patches/nss/ath11k/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch rename to package/kernel/mac80211/patches/nss/ath11k/318-ath11k-avoid-stack-corrupt-in-nwifi-undecap.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch b/package/kernel/mac80211/patches/nss/ath11k/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch similarity index 96% rename from package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch rename to package/kernel/mac80211/patches/nss/ath11k/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch index 7ea6b471e3..d733219b38 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/319-ath11k-fix-double-free-of-peer-rx_tid-during-reo-cmd.patch @@ -30,7 +30,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -1435,6 +1435,7 @@ const struct ath11k_hw_ring_mask ath11k_ +@@ -1332,6 +1332,7 @@ const struct ath11k_hw_ring_mask ath11k_ ATH11K_RX_WBM_REL_RING_MASK_0, }, .reo_status = { diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch similarity index 94% rename from package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch rename to package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch index 6ebd709e7d..01ccc6003f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-330-ath11k-sync-wds_ast_entry-updates.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/330-ath11k-sync-wds_ast_entry-updates.patch @@ -56,7 +56,7 @@ Signed-off-by: Rameshkumar Sundaram static void ath11k_ahb_free_resources(struct ath11k_base *ab) --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -2230,6 +2230,7 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2211,6 +2211,7 @@ struct ath11k_base *ath11k_core_alloc(st mutex_init(&ab->core_lock); mutex_init(&ab->tbl_mtx_lock); @@ -64,7 +64,7 @@ Signed-off-by: Rameshkumar Sundaram spin_lock_init(&ab->base_lock); mutex_init(&ab->vdev_id_11d_lock); init_completion(&ab->reset_complete); -@@ -2243,6 +2244,8 @@ struct ath11k_base *ath11k_core_alloc(st +@@ -2224,6 +2225,8 @@ struct ath11k_base *ath11k_core_alloc(st INIT_WORK(&ab->restart_work, ath11k_core_restart); INIT_WORK(&ab->update_11d_work, ath11k_update_11d); INIT_WORK(&ab->reset_work, ath11k_core_reset); @@ -75,29 +75,27 @@ Signed-off-by: Rameshkumar Sundaram init_completion(&ab->wow.wakeup_completed); --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -32,6 +32,7 @@ +@@ -31,6 +31,7 @@ + #include "wow.h" #include "rx_desc.h" #include "nss.h" - #include "vendor.h" +#include "peer.h" #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -@@ -1131,6 +1132,11 @@ struct ath11k_base { +@@ -1080,6 +1081,9 @@ struct ath11k_base { u32 max_ast_index; u32 num_ast_entries; -+ + struct mutex base_ast_lock; + struct work_struct wmi_ast_work; + struct list_head wmi_ast_list; -+ + + bool stats_disable; /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); - }; --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -691,8 +691,9 @@ static void ath11k_nss_wds_type_rx(struc +@@ -647,8 +647,9 @@ static void ath11k_nss_wds_type_rx(struc spin_unlock_bh(&ab->base_lock); } @@ -108,7 +106,7 @@ Signed-off-by: Rameshkumar Sundaram struct ath11k_base *ab = ar->ab; struct ath11k_peer *peer = ar->bss_peer; u8 mac_addr[ETH_ALEN]; -@@ -719,7 +720,7 @@ static void ath11k_nss_mec_handler(struc +@@ -675,7 +676,7 @@ static void ath11k_nss_mec_handler(struc memcpy(mac_addr, mac_addr_h16, ETH_ALEN - 4); memcpy(mac_addr + 2, mac_addr_l32, 4); @@ -117,7 +115,7 @@ Signed-off-by: Rameshkumar Sundaram spin_lock_bh(&ab->base_lock); ath11k_peer_add_ast(ar, peer, mac_addr, ATH11K_AST_TYPE_MEC); -@@ -754,7 +755,7 @@ static void ath11k_nss_vdev_spl_receive_ +@@ -710,7 +711,7 @@ static void ath11k_nss_vdev_spl_receive_ addr4_valid, peer_id); break; case NSS_WIFI_VDEV_WDS_TYPE_MEC: @@ -126,7 +124,7 @@ Signed-off-by: Rameshkumar Sundaram break; default: ath11k_warn(ab, "unsupported wds_type %d\n", wds_type); -@@ -3848,11 +3849,7 @@ int ath11k_nss_add_wds_peer(struct ath11 +@@ -3796,11 +3797,7 @@ int ath11k_nss_add_wds_peer(struct ath11 wds_peer_msg->ast_type = type; wds_peer_msg->peer_id = peer->peer_id; @@ -139,7 +137,7 @@ Signed-off-by: Rameshkumar Sundaram ether_addr_copy(wds_peer_msg->dest_mac, dest_mac); msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; -@@ -3975,7 +3972,7 @@ msg_free: +@@ -3923,7 +3920,7 @@ msg_free: return ret; } @@ -148,7 +146,7 @@ Signed-off-by: Rameshkumar Sundaram u8 *dest_mac) { struct ath11k_base *ab = ar->ab; -@@ -3993,8 +3990,8 @@ int ath11k_nss_del_wds_peer(struct ath11 +@@ -3941,8 +3938,8 @@ int ath11k_nss_del_wds_peer(struct ath11 wds_peer_msg->pdev_id = ar->pdev->pdev_id; wds_peer_msg->ast_type = ATH11K_AST_TYPE_NONE; @@ -161,7 +159,7 @@ Signed-off-by: Rameshkumar Sundaram msg_cb = (nss_wifili_msg_callback_t)ath11k_nss_wifili_event_receive; --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -291,8 +291,8 @@ int ath11k_nss_update_wds_peer(struct at +@@ -290,8 +290,8 @@ int ath11k_nss_update_wds_peer(struct at u8 *dest_mac); int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, u8 *dest_mac, enum ath11k_ast_entry_type type); @@ -172,7 +170,7 @@ Signed-off-by: Rameshkumar Sundaram int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif, u8 *wds_addr, u32 wds_peer_id); int ath11k_nss_ext_vdev_wds_4addr_allow(struct ath11k_vif *arvif, -@@ -404,8 +404,8 @@ static inline int ath11k_nss_map_wds_pee +@@ -413,8 +413,8 @@ static inline int ath11k_nss_map_wds_pee return 0; } @@ -185,7 +183,7 @@ Signed-off-by: Rameshkumar Sundaram } --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c -@@ -970,6 +970,7 @@ static void ath11k_pci_remove(struct pci +@@ -972,6 +972,7 @@ static void ath11k_pci_remove(struct pci } set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); @@ -494,7 +492,7 @@ Signed-off-by: Rameshkumar Sundaram if (ret) { --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -31,9 +31,7 @@ enum ath11k_wds_wmi_action { +@@ -42,9 +42,7 @@ enum ath11k_wds_wmi_action { struct ath11k_ast_entry { u16 ast_idx; u8 addr[ETH_ALEN]; @@ -504,15 +502,18 @@ Signed-off-by: Rameshkumar Sundaram struct ath11k_peer *peer; struct ath11k *ar; bool next_hop; -@@ -47,6 +45,7 @@ struct ath11k_ast_entry { - bool delete_in_progress; +@@ -55,9 +53,9 @@ struct ath11k_ast_entry { + u16 ast_hash_value; + int ref_cnt; + enum ath11k_ast_entry_type type; +- bool delete_in_progress; void *cookie; struct list_head ase_list; + struct list_head wmi_list; }; - struct ppdu_user_delayba { -@@ -97,6 +96,7 @@ struct ath11k_peer { + struct ath11k_peer { +@@ -97,6 +95,7 @@ struct ath11k_peer { bool dp_setup_done; struct ppdu_user_delayba ppdu_stats_delayba; bool delayba_flag; diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch b/package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch similarity index 82% rename from package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch rename to package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch index 3cc13d1ba9..60f3b24655 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-335-0001-ath11k-optimize-tx-completions.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/335-0001-ath11k-optimize-tx-completions.patch @@ -13,15 +13,7 @@ Signed-off-by: Venkateswara Naralasetty --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -439,6 +439,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct - return; - } - -+ - if (skb_cb->pkt_offset) - skb_pull(msdu, skb_cb->pkt_offset); /* removing the alignment and htt meta data */ - -@@ -637,9 +638,41 @@ err_out: +@@ -651,9 +651,41 @@ err_out: spin_unlock_bh(&ab->base_lock); } @@ -64,12 +56,11 @@ Signed-off-by: Venkateswara Naralasetty { struct ieee80211_tx_status status = { 0 }; struct ieee80211_rate_status status_rate = { 0 }; -@@ -649,9 +682,12 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -663,9 +695,11 @@ static void ath11k_dp_tx_complete_msdu(s struct ath11k_peer *peer; struct ath11k_sta *arsta; struct rate_info rate; + struct hal_tx_status ts = { 0 }; -+ enum hal_wbm_htt_tx_comp_status wbm_status; + enum hal_wbm_tqm_rel_reason rel_status; u8 flags = 0; @@ -78,7 +69,7 @@ Signed-off-by: Venkateswara Naralasetty /* Must not happen */ return; } -@@ -660,11 +696,14 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -674,11 +708,14 @@ static void ath11k_dp_tx_complete_msdu(s dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); @@ -95,7 +86,7 @@ Signed-off-by: Venkateswara Naralasetty } if (skb_has_frag_list(msdu)) { kfree_skb_list(skb_shinfo(msdu)->frag_list); -@@ -674,6 +713,8 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -688,6 +725,8 @@ static void ath11k_dp_tx_complete_msdu(s return; } @@ -104,15 +95,7 @@ Signed-off-by: Venkateswara Naralasetty if (unlikely(!rcu_access_pointer(ab->pdevs_active[ar->pdev_idx]))) { ieee80211_free_txskb(ar->hw, msdu); return; -@@ -684,54 +725,56 @@ static void ath11k_dp_tx_complete_msdu(s - return; - } - -+ wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS, -+ tx_status->info0); - info = IEEE80211_SKB_CB(msdu); - memset(&info->status, 0, sizeof(info->status)); - +@@ -704,48 +743,48 @@ static void ath11k_dp_tx_complete_msdu(s /* skip tx rate update from ieee80211_status*/ info->status.rates[0].idx = -1; @@ -173,7 +156,7 @@ Signed-off-by: Venkateswara Naralasetty spin_unlock_bh(&ab->base_lock); ieee80211_free_txskb(ar->hw, msdu); return; -@@ -753,44 +796,13 @@ static void ath11k_dp_tx_complete_msdu(s +@@ -767,37 +806,6 @@ static void ath11k_dp_tx_complete_msdu(s ieee80211_tx_status_ext(ar->hw, &status); } @@ -211,15 +194,7 @@ Signed-off-by: Venkateswara Naralasetty static inline bool ath11k_dp_tx_completion_valid(struct hal_wbm_release_ring *desc) { struct htt_tx_wbm_completion *status_desc; - - if (FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0) == - HAL_WBM_REL_SRC_MODULE_FW) { -- status_desc = ((u8 *)desc) + HTT_TX_WBM_COMP_STATUS_OFFSET; -+ status_desc = ((struct htt_tx_wbm_completion *)desc) + HTT_TX_WBM_COMP_STATUS_OFFSET; - - /* Dont consider HTT_TX_COMP_STATUS_MEC_NOTIFY */ - if (FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS, status_desc->info0) == -@@ -807,9 +819,9 @@ void ath11k_dp_tx_completion_handler(str +@@ -821,9 +829,9 @@ void ath11k_dp_tx_completion_handler(str int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id, count = 0, i = 0; struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id]; struct sk_buff *msdu; @@ -230,16 +205,7 @@ Signed-off-by: Venkateswara Naralasetty u32 *desc; u32 msdu_id, desc_id; u8 mac_id; -@@ -829,7 +841,7 @@ void ath11k_dp_tx_completion_handler(str - ath11k_hal_srng_dst_invalidate_entry(ab, status_ring, valid_entries); - - while ((desc = ath11k_hal_srng_dst_get_next_cache_entry(ab, status_ring))) { -- if (!ath11k_dp_tx_completion_valid(desc)) -+ if (!ath11k_dp_tx_completion_valid((struct hal_wbm_release_ring *)desc)) - continue; - - memcpy(&tx_ring->tx_status[count], -@@ -849,14 +861,16 @@ void ath11k_dp_tx_completion_handler(str +@@ -863,14 +871,16 @@ void ath11k_dp_tx_completion_handler(str while (count--) { tx_status = &tx_ring->tx_status[i++]; @@ -258,7 +224,7 @@ Signed-off-by: Venkateswara Naralasetty ath11k_dp_tx_process_htt_tx_complete(ab, (void *)tx_status, mac_id, msdu_id, -@@ -880,7 +894,7 @@ void ath11k_dp_tx_completion_handler(str +@@ -894,7 +904,7 @@ void ath11k_dp_tx_completion_handler(str if (atomic_dec_and_test(&ar->dp.num_tx_pending)) wake_up(&ar->dp.tx_empty_waitq); diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch b/package/kernel/mac80211/patches/nss/ath11k/335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch similarity index 90% rename from package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch rename to package/kernel/mac80211/patches/nss/ath11k/335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch index 7b87edb0ae..f567ec6409 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/335-0002-ath11k-use-DECLARE_BITMAP-for-idr-operations.patch @@ -18,7 +18,7 @@ Signed-off-by: Venkateswara Naralasetty --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -380,6 +380,8 @@ static void ath11k_dp_srng_common_cleanu +@@ -376,6 +376,8 @@ static void ath11k_dp_srng_common_cleanu for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) { ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring); ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring); @@ -27,7 +27,7 @@ Signed-off-by: Venkateswara Naralasetty } ath11k_dp_srng_cleanup(ab, &dp->reo_reinject_ring); ath11k_dp_srng_cleanup(ab, &dp->rx_rel_ring); -@@ -392,7 +394,7 @@ static int ath11k_dp_srng_common_setup(s +@@ -388,7 +390,7 @@ static int ath11k_dp_srng_common_setup(s { struct ath11k_dp *dp = &ab->dp; struct hal_srng *srng; @@ -36,7 +36,7 @@ Signed-off-by: Venkateswara Naralasetty u8 tcl_num, wbm_num; ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring, -@@ -451,6 +453,18 @@ static int ath11k_dp_srng_common_setup(s +@@ -447,6 +449,18 @@ static int ath11k_dp_srng_common_setup(s ath11k_dp_shadow_init_timer(ab, &dp->tx_ring_timer[i], ATH11K_SHADOW_DP_TIMER_INTERVAL, dp->tx_ring[i].tcl_data_ring.ring_id); @@ -55,7 +55,7 @@ Signed-off-by: Venkateswara Naralasetty } ret = ath11k_dp_srng_setup(ab, &dp->reo_reinject_ring, HAL_REO_REINJECT, -@@ -1039,9 +1053,8 @@ void ath11k_dp_vdev_tx_attach(struct ath +@@ -1031,9 +1045,8 @@ void ath11k_dp_vdev_tx_attach(struct ath ath11k_dp_update_vdev_search(arvif); } @@ -66,15 +66,13 @@ Signed-off-by: Venkateswara Naralasetty struct sk_buff *msdu = skb; dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len, -@@ -1056,23 +1069,30 @@ void ath11k_dp_free(struct ath11k_base * +@@ -1047,21 +1060,28 @@ static int ath11k_dp_tx_pending_cleanup( + void ath11k_dp_free(struct ath11k_base *ab) { struct ath11k_dp *dp = &ab->dp; - size_t size = 0; - int i; + int i, j; - size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE; - ath11k_dp_link_desc_cleanup(ab, dp->link_desc_banks, HAL_WBM_IDLE_LINK, &dp->wbm_idle_ring); @@ -100,9 +98,9 @@ Signed-off-by: Venkateswara Naralasetty - ath11k_dp_tx_pending_cleanup, ab); - idr_destroy(&dp->tx_ring[i].txbuf_idr); - spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock); - ATH11K_MEMORY_STATS_DEC(ab, malloc_size, size); kfree(dp->tx_ring[i].tx_status); } + --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -8,6 +8,7 @@ @@ -141,12 +139,12 @@ Signed-off-by: Venkateswara Naralasetty #define DP_TCL_DATA_RING_SIZE_WCN6750 2048 #define DP_TX_COMP_RING_SIZE ATH11K_DP_TX_COMP_RING_SIZE -#define DP_TX_IDR_SIZE DP_TX_COMP_RING_SIZE - #define DP_TX_COMP_MAX_ALLOWED DP_TX_COMP_RING_SIZE + #define DP_TX_COMP_MAX_ALLOWED DP_TX_COMP_RING_SIZE #define DP_TCL_CMD_RING_SIZE 32 #define DP_TCL_STATUS_RING_SIZE 32 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -122,6 +122,7 @@ int ath11k_dp_tx(struct ath11k *ar, stru +@@ -135,6 +135,7 @@ int ath11k_dp_tx(struct ath11k *ar, stru u8 ring_map = 0; bool tcl_ring_retry, is_diff_encap = false; u8 align_pad, htt_meta_size = 0, max_tx_ring, tcl_ring_id, ring_id; @@ -154,7 +152,7 @@ Signed-off-by: Venkateswara Naralasetty if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && !ieee80211_is_data(hdr->frame_control))) -@@ -152,24 +153,28 @@ tcl_ring_sel: +@@ -164,24 +165,28 @@ tcl_ring_sel: tx_ring = &dp->tx_ring[tcl_ring_id]; spin_lock_bh(&tx_ring->tx_idr_lock); @@ -189,7 +187,7 @@ Signed-off-by: Venkateswara Naralasetty FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id); ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb); -@@ -341,10 +346,9 @@ fail_unmap_dma: +@@ -355,10 +360,9 @@ fail_unmap_dma: fail_remove_idr: if (ti.pkt_offset) skb_pull(skb, ti.pkt_offset); @@ -203,7 +201,7 @@ Signed-off-by: Venkateswara Naralasetty if (tcl_ring_retry) goto tcl_ring_sel; -@@ -353,16 +357,19 @@ fail_remove_idr: +@@ -367,16 +371,19 @@ fail_remove_idr: } static void ath11k_dp_tx_free_txbuf(struct ath11k_base *ab, u8 mac_id, @@ -228,7 +226,7 @@ Signed-off-by: Venkateswara Naralasetty if (unlikely(!msdu)) { ath11k_warn(ab, "tx completion for unknown msdu_id %d\n", -@@ -386,16 +393,20 @@ ath11k_dp_tx_htt_tx_complete_buf(struct +@@ -400,16 +407,20 @@ ath11k_dp_tx_htt_tx_complete_buf(struct struct ath11k_dp_htt_wbm_tx_status *ts) { struct ieee80211_tx_status status = { 0 }; @@ -253,7 +251,7 @@ Signed-off-by: Venkateswara Naralasetty if (unlikely(!msdu)) { ath11k_warn(ab, "htt tx completion for unknown msdu_id %d\n", -@@ -860,6 +871,7 @@ void ath11k_dp_tx_completion_handler(str +@@ -870,6 +881,7 @@ void ath11k_dp_tx_completion_handler(str } while (count--) { @@ -261,7 +259,7 @@ Signed-off-by: Venkateswara Naralasetty tx_status = &tx_ring->tx_status[i++]; desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, -@@ -878,17 +890,19 @@ void ath11k_dp_tx_completion_handler(str +@@ -888,17 +900,19 @@ void ath11k_dp_tx_completion_handler(str continue; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch b/package/kernel/mac80211/patches/nss/ath11k/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch similarity index 81% rename from package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch rename to package/kernel/mac80211/patches/nss/ath11k/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch index 1bfbd0ebdb..8e018e619f 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -35,18 +35,7 @@ Signed-off-by: Venkateswara Naralasetty enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher) { switch (cipher) { -@@ -143,9 +130,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru - !ieee80211_is_data(hdr->frame_control))) - return -ENOTSUPP; - -- pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1); -- - ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb); -+ pool_id = ring_selector; - - tcl_ring_sel: - tcl_ring_retry = false; -@@ -221,10 +207,6 @@ tcl_ring_sel: +@@ -232,10 +219,6 @@ tcl_ring_sel: if (ieee80211_vif_is_mesh(arvif->vif)) ti.enable_mesh = true; @@ -62,14 +51,14 @@ Signed-off-by: Venkateswara Naralasetty @@ -65,7 +65,6 @@ void ath11k_hal_tx_cmd_desc_setup(struct FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_PKT_OFFSET, ti->pkt_offset); - tcl_cmd->info2 = ti->flags1 | + tcl_cmd.info2 = ti->flags1 | - FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID, ti->tid) | FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ti->lmac_id); - tcl_cmd->info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX, + tcl_cmd.info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX, --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -9682,6 +9682,8 @@ static int __ath11k_mac_register(struct +@@ -10150,6 +10150,8 @@ static int __ath11k_mac_register(struct ieee80211_hw_set(ar->hw, USES_RSS); } diff --git a/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-Fix-updating-rx-stats-with-monitor-vif-enable.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-Fix-updating-rx-stats-with-monitor-vif-enable.patch new file mode 100644 index 0000000000..752218e9b8 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-Fix-updating-rx-stats-with-monitor-vif-enable.patch @@ -0,0 +1,88 @@ +From 00d07d474f2ee3aa8aa2945fc26e473183e9201a Mon Sep 17 00:00:00 2001 +From: Anilkumar Kolli +Date: Fri, 17 Dec 2021 17:16:11 +0530 +Subject: [PATCH] ath11k: Fix updating rx stats with monitor vif enabled + +Rx stats update fails when monitor vif is enabled. +Current code does not update rx stats from monitor +status ring if monitor vif is enabled. +Add logic to update rx stats even if monitor vif enabled. + +Fixes: 1f49c59c7222 ("mac80211: Package upgrade") + +Signed-off-by: Anilkumar Kolli +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 96 ++++++---------------- + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -5953,12 +5953,23 @@ int ath11k_dp_rx_process_mon_status(stru + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + } + +- if (ppdu_info->peer_id == HAL_INVALID_PEERID || +- hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { ++ if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) && ++ hal_status == HAL_RX_MON_STATUS_PPDU_DONE && ++ pmon->mon_ppdu_status == DP_PPDU_STATUS_START) { ++ rx_mon_stats->status_ppdu_done++; ++ pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; ++ ++ if (!ab->hw_params.full_monitor_mode) { ++ ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi); ++ pmon->mon_ppdu_status = DP_PPDU_STATUS_START; ++ } ++ } ++ ++ if ((ppdu_info->peer_id == HAL_INVALID_PEERID || ++ hal_status != HAL_RX_MON_STATUS_PPDU_DONE)) { + dev_kfree_skb_any(skb); + continue; + } +- + rcu_read_lock(); + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_id(ab, ppdu_info->peer_id); +@@ -6282,6 +6293,13 @@ static int ath11k_dp_full_mon_process_rx + + spin_lock_bh(&pmon->mon_lock); + ++ pmon->mon_ppdu_status = DP_PPDU_STATUS_START; ++ if (!test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) { ++ quota = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget); ++ spin_unlock_bh(&pmon->mon_lock); ++ return quota; ++ } ++ + sw_mon_entries = &pmon->sw_mon_entries; + rx_mon_stats = &pmon->rx_mon_stats; + +@@ -6321,7 +6339,6 @@ static int ath11k_dp_full_mon_process_rx + } + + rx_mon_stats->dest_ppdu_done++; +- pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + pmon->buf_state = DP_MON_STATUS_LAG; + pmon->mon_status_paddr = sw_mon_entries->mon_status_paddr; + pmon->hold_mon_dst_ring = true; +@@ -6352,16 +6369,10 @@ reap_status_ring: + int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id, + struct napi_struct *napi, int budget) + { +- struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id); +- int ret = 0; +- +- if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) && +- ab->hw_params.full_monitor_mode) +- ret = ath11k_dp_full_mon_process_rx(ab, mac_id, napi, budget); +- else +- ret = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget); +- +- return ret; ++ if (ab->hw_params.full_monitor_mode) ++ return ath11k_dp_full_mon_process_rx(ab, mac_id, napi, budget); ++ else ++ return ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget); + } + + static int ath11k_dp_rx_pdev_mon_status_attach(struct ath11k *ar) diff --git a/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch similarity index 95% rename from package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch rename to package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch index 2e874d321d..0adf26c808 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/336-ath11k-skip-status-ring-entry-processing.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/336-ath11k-skip-status-ring-entry-processing.patch @@ -35,7 +35,7 @@ Signed-off-by: Venkateswara Naralasetty --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3296,6 +3296,46 @@ ath11k_dp_rx_mon_update_status_buf_state +@@ -3660,6 +3660,46 @@ ath11k_dp_rx_mon_update_status_buf_state } } @@ -82,7 +82,7 @@ Signed-off-by: Venkateswara Naralasetty static int ath11k_dp_rx_reap_mon_status_ring(struct ath11k_base *ab, int mac_id, int *budget, struct sk_buff_head *skb_list) { -@@ -3309,6 +3349,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3673,6 +3713,7 @@ static int ath11k_dp_rx_reap_mon_status_ struct sk_buff *skb; struct ath11k_skb_rxcb *rxcb; struct hal_tlv_hdr *tlv; @@ -90,7 +90,7 @@ Signed-off-by: Venkateswara Naralasetty u32 cookie; int buf_id, srng_id; dma_addr_t paddr; -@@ -3328,8 +3369,7 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3692,8 +3733,7 @@ static int ath11k_dp_rx_reap_mon_status_ ath11k_hal_srng_access_begin(ab, srng); while (*budget) { *budget -= 1; @@ -100,7 +100,7 @@ Signed-off-by: Venkateswara Naralasetty if (!rx_mon_status_desc) { pmon->buf_state = DP_MON_STATUS_REPLINISH; break; -@@ -3360,18 +3400,43 @@ static int ath11k_dp_rx_reap_mon_status_ +@@ -3724,18 +3764,43 @@ static int ath11k_dp_rx_reap_mon_status_ tlv = (struct hal_tlv_hdr *)skb->data; if (FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl) != HAL_RX_STATUS_BUFFER_DONE) { @@ -180,7 +180,7 @@ Signed-off-by: Venkateswara Naralasetty lockdep_assert_held(&srng->lock); --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h -@@ -953,6 +953,8 @@ int ath11k_hal_srng_dst_num_free(struct +@@ -952,6 +952,8 @@ int ath11k_hal_srng_dst_num_free(struct void ath11k_hal_srng_dst_invalidate_entry(struct ath11k_base *ab, struct hal_srng *srng, int entries); u32 *ath11k_hal_srng_src_peek(struct ath11k_base *ab, struct hal_srng *srng); diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch b/package/kernel/mac80211/patches/nss/ath11k/341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch similarity index 97% rename from package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch rename to package/kernel/mac80211/patches/nss/ath11k/341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch index a1b885c8b5..9a3c95a9df 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/341-ath11k-fix-support-for-ext-vdev-in-NSS-for-AP_VLAN-v.patch @@ -38,7 +38,7 @@ Signed-off-by: Aditya Kumar Singh --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -2010,6 +2010,11 @@ static int ath11k_core_reconfigure_on_cr +@@ -1837,6 +1837,11 @@ static int ath11k_core_reconfigure_on_cr clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); diff --git a/package/kernel/mac80211/patches/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch b/package/kernel/mac80211/patches/nss/ath11k/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch similarity index 100% rename from package/kernel/mac80211/patches/ath11k_nss/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch rename to package/kernel/mac80211/patches/nss/ath11k/342-ath11k-provide-access-of-the-dma-buffer-back-to-dma-.patch diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch b/package/kernel/mac80211/patches/nss/ath11k/353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch similarity index 98% rename from package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch rename to package/kernel/mac80211/patches/nss/ath11k/353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch index e8ac589acf..0e99521c4d 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/353-ath11k-ignore-frags-from-uninitialized-peer-in-dp.patch @@ -64,7 +64,7 @@ Signed-off-by: Nagarajan Maran --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h -@@ -93,6 +93,7 @@ struct ath11k_peer { +@@ -92,6 +92,7 @@ struct ath11k_peer { u16 sec_type; u16 sec_type_grp; bool is_authorized; diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch similarity index 86% rename from package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch rename to package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch index 4e7e37957b..f574597dce 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-356-ath11k-invalid-desc-sanity-check.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/356-ath11k-invalid-desc-sanity-check.patch @@ -46,7 +46,18 @@ Signed-off-by: Nagarajan Maran --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -3228,6 +3228,16 @@ try_again: +@@ -396,8 +396,8 @@ int ath11k_dp_rxbufs_replenish(struct at + goto fail_free_skb; + + spin_lock_bh(&rx_ring->idr_lock); +- buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1, +- (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC); ++ buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1, ++ (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC); + spin_unlock_bh(&rx_ring->idr_lock); + if (buf_id <= 0) + goto fail_dma_unmap; +@@ -3141,6 +3141,16 @@ try_again: while (likely(desc = (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab, srng))) { @@ -63,7 +74,7 @@ Signed-off-by: Nagarajan Maran cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, desc->buf_addr_info.info1); buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID, -@@ -3258,8 +3268,6 @@ try_again: +@@ -3171,8 +3181,6 @@ try_again: num_buffs_reaped[mac_id]++; diff --git a/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch b/package/kernel/mac80211/patches/nss/ath11k/357-ath11k-fix-clear-peer-keys-during-disassoc.patch similarity index 92% rename from package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch rename to package/kernel/mac80211/patches/nss/ath11k/357-ath11k-fix-clear-peer-keys-during-disassoc.patch index 414cb06d87..4c7fefbba1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/357-ath11k-fix-clear-peer-keys-during-disassoc.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/357-ath11k-fix-clear-peer-keys-during-disassoc.patch @@ -17,7 +17,7 @@ Signed-off-by: Karthikeyan Kathirvel --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -4712,12 +4712,6 @@ static int ath11k_station_disassoc(struc +@@ -4894,12 +4894,6 @@ static int ath11k_station_disassoc(struc return ret; } @@ -30,7 +30,7 @@ Signed-off-by: Karthikeyan Kathirvel return 0; } -@@ -5180,6 +5174,17 @@ static int ath11k_mac_op_sta_state(struc +@@ -5490,6 +5484,17 @@ static int ath11k_mac_op_sta_state(struc arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); arsta->bw_prev = arsta->bw; spin_unlock_bh(&ar->data_lock); diff --git a/package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch b/package/kernel/mac80211/patches/nss/ath11k/362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch similarity index 82% rename from package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch rename to package/kernel/mac80211/patches/nss/ath11k/362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch index f734c5aea8..3786bd3de9 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/908-362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/362-ath11k-fix-incorrect-ast-index-assignment-for-wds-peer.patch @@ -19,16 +19,7 @@ Signed-off-by: Raj Kumar Bhagat --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -805,8 +805,6 @@ ath11k_nss_vdev_special_data_receive(str - struct nss_wifi_vdev_per_packet_metadata *wifi_metadata = NULL; - struct nss_wifi_vdev_wds_per_packet_metadata *wds_metadata = NULL; - struct nss_wifi_vdev_addr4_data_metadata *addr4_metadata = NULL; -- struct wireless_dev *wdev; -- struct ieee80211_vif *vif; - struct ath11k_vif *arvif; - struct ath11k_base *ab; - struct ath11k_skb_rxcb *rxcb; -@@ -2487,13 +2485,14 @@ msg_free: +@@ -3871,13 +3871,14 @@ msg_free: } int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, @@ -44,7 +35,7 @@ Signed-off-by: Raj Kumar Bhagat int ret = 0; wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); -@@ -2503,7 +2502,7 @@ int ath11k_nss_map_wds_peer(struct ath11 +@@ -3887,7 +3888,7 @@ int ath11k_nss_map_wds_peer(struct ath11 wds_peer_map_msg = &wlmsg->msg.wdspeermapmsg; wds_peer_map_msg->vdev_id = peer->vdev_id; @@ -55,7 +46,7 @@ Signed-off-by: Raj Kumar Bhagat wds_peer_map_msg->peer_id = NSS_WIFILI_MEC_PEER_ID; --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -16,6 +16,7 @@ struct ath11k; +@@ -20,6 +20,7 @@ struct ath11k; struct ath11k_base; struct ath11k_vif; struct ath11k_peer; @@ -63,7 +54,7 @@ Signed-off-by: Raj Kumar Bhagat struct ath11k_sta; enum ath11k_ast_entry_type; struct hal_rx_mon_ppdu_info; -@@ -241,7 +242,7 @@ int ath11k_nss_add_wds_peer(struct ath11 +@@ -289,7 +290,7 @@ int ath11k_nss_add_wds_peer(struct ath11 int ath11k_nss_update_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, u8 *dest_mac); int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, @@ -72,7 +63,7 @@ Signed-off-by: Raj Kumar Bhagat int ath11k_nss_del_wds_peer(struct ath11k *ar, u8 *peer_addr, int peer_id, u8 *dest_mac); int ath11k_nss_ext_vdev_cfg_wds_peer(struct ath11k_vif *arvif, -@@ -337,7 +338,8 @@ static inline int ath11k_nss_update_wds_ +@@ -408,7 +409,8 @@ static inline int ath11k_nss_update_wds_ } static inline int ath11k_nss_map_wds_peer(struct ath11k *ar, struct ath11k_peer *peer, diff --git a/package/kernel/mac80211/patches/nss/ath11k/371-ath11k-Fix-ppdu_id-from-firmware-PPDU-stats.patch b/package/kernel/mac80211/patches/nss/ath11k/371-ath11k-Fix-ppdu_id-from-firmware-PPDU-stats.patch new file mode 100644 index 0000000000..f909ba4a67 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/371-ath11k-Fix-ppdu_id-from-firmware-PPDU-stats.patch @@ -0,0 +1,52 @@ +From 537a8f2292ba9052957e8284161bcee0635e4223 Mon Sep 17 00:00:00 2001 +From: Ramya Gnanasekar +Date: Tue, 11 Apr 2023 14:15:36 +0530 +Subject: [PATCH] ath11k: Fix ppdu_id from firmware PPDU stats + +ppdu_id in USR_COMPLTN_ACK_BA_STATUS TLV will have firmware meta data +last 7 bits. +When ppdu_id is taken as such, during parsing this is treated as different +ppdu_id which causes incorrect stats update. Since firmware will use +this MSB 7 bits for internal accounting and optimization, +it is recommended to use first 25 bits when fetching ppdu for USR_COMPLTN_ACK_BA_STATUS. + +Signed-off-by: Ramya Gnanasekar + +--- a/drivers/net/wireless/ath/ath11k/dp.h ++++ b/drivers/net/wireless/ath/ath11k/dp.h +@@ -1425,6 +1425,7 @@ struct htt_ppdu_stats_usr_cmpltn_cmn { + #define HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM GENMASK(31, 25) + + #define HTT_PPDU_STATS_NON_QOS_TID 16 ++#define HTT_PPDU_STATS_PPDU_ID GENMASK(24, 0) + + struct htt_ppdu_stats_usr_cmpltn_ack_ba_status { + u32 ppdu_id; +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1288,7 +1288,7 @@ static int ath11k_htt_tlv_ppdu_stats_par + struct htt_ppdu_user_stats *user_stats = NULL; + int cur_user; + u16 peer_id; +- u32 frame_type; ++ u32 frame_type, ppdu_id; + + ppdu_info = data; + +@@ -1369,6 +1369,8 @@ static int ath11k_htt_tlv_ppdu_stats_par + return -EINVAL; + } + ++ ppdu_id = ++ ((struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *)ptr)->ppdu_id; + peer_id = + ((struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *)ptr)->sw_peer_id; + cur_user = ath11k_get_ppdu_user_index(&ppdu_info->ppdu_stats, +@@ -1380,6 +1382,7 @@ static int ath11k_htt_tlv_ppdu_stats_par + user_stats->is_valid_peer_id = true; + memcpy((void *)&user_stats->ack_ba, ptr, + sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)); ++ ppdu_info->ppdu_id = FIELD_GET(HTT_PPDU_STATS_PPDU_ID, ppdu_id); + user_stats->tlv_flags |= BIT(tag); + break; + case HTT_PPDU_STATS_TAG_USR_COMMON: diff --git a/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch b/package/kernel/mac80211/patches/nss/ath11k/373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch similarity index 94% rename from package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch rename to package/kernel/mac80211/patches/nss/ath11k/373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch index 90f335efbc..8adb5448a1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/911-373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/373-ath11k-Add-retry-mechanism-for-update_rx_qu.patch @@ -41,7 +41,7 @@ Signed-off-by: Tamizh Chelvam Raja --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h -@@ -936,6 +936,9 @@ struct ath11k_soc_dp_stats { +@@ -902,6 +902,9 @@ struct ath11k_soc_dp_stats { u32 rxdma_error[HAL_REO_ENTR_RING_RXDMA_ECODE_MAX]; u32 reo_error[HAL_REO_DEST_RING_ERROR_CODE_MAX]; u32 hal_reo_error[DP_REO_DST_RING_MAX]; @@ -53,7 +53,7 @@ Signed-off-by: Tamizh Chelvam Raja }; --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -851,6 +851,18 @@ static ssize_t ath11k_debugfs_dump_soc_d +@@ -848,6 +848,18 @@ static ssize_t ath11k_debugfs_dump_soc_d "\nNSS Transmit Failures: %d\n", atomic_read(&soc_stats->tx_err.nss_tx_fail)); @@ -74,7 +74,7 @@ Signed-off-by: Tamizh Chelvam Raja if (len > size) --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -1113,8 +1113,10 @@ int ath11k_dp_alloc(struct ath11k_base * +@@ -1102,8 +1102,10 @@ int ath11k_dp_alloc(struct ath11k_base * INIT_LIST_HEAD(&dp->reo_cmd_list); INIT_LIST_HEAD(&dp->reo_cmd_cache_flush_list); @@ -110,7 +110,7 @@ Signed-off-by: Tamizh Chelvam Raja struct dp_reo_cmd { struct list_head list; struct dp_rx_tid data; -@@ -296,6 +305,12 @@ struct ath11k_dp { +@@ -295,6 +304,12 @@ struct ath11k_dp { * - reo_cmd_cache_flush_count */ spinlock_t reo_cmd_lock; @@ -135,7 +135,7 @@ Signed-off-by: Tamizh Chelvam Raja static inline u8 *ath11k_dp_rx_h_80211_hdr(struct ath11k_base *ab, struct hal_rx_desc *desc) { -@@ -707,13 +710,50 @@ static int ath11k_dp_rx_pdev_srng_alloc( +@@ -672,13 +675,50 @@ static int ath11k_dp_rx_pdev_srng_alloc( return 0; } @@ -186,7 +186,7 @@ Signed-off-by: Tamizh Chelvam Raja spin_lock_bh(&dp->reo_cmd_lock); list_for_each_entry_safe(cmd, tmp, &dp->reo_cmd_list, list) { list_del(&cmd->list); -@@ -759,14 +799,18 @@ static void ath11k_dp_reo_cmd_free(struc +@@ -724,14 +764,18 @@ static void ath11k_dp_reo_cmd_free(struc } } @@ -207,7 +207,7 @@ Signed-off-by: Tamizh Chelvam Raja desc_sz = ath11k_hal_reo_qdesc_size(0, HAL_DESC_REO_NON_QOS_TID); while (tot_desc_sz > desc_sz) { -@@ -777,11 +821,17 @@ static void ath11k_dp_reo_cache_flush(st +@@ -742,11 +786,17 @@ static void ath11k_dp_reo_cache_flush(st HAL_REO_CMD_FLUSH_CACHE, &cmd, NULL); if (ret) @@ -228,7 +228,7 @@ Signed-off-by: Tamizh Chelvam Raja memset(&cmd, 0, sizeof(cmd)); cmd.addr_lo = lower_32_bits(rx_tid->paddr); cmd.addr_hi = upper_32_bits(rx_tid->paddr); -@@ -789,24 +839,21 @@ static void ath11k_dp_reo_cache_flush(st +@@ -754,24 +804,21 @@ static void ath11k_dp_reo_cache_flush(st ret = ath11k_dp_tx_send_reo_cmd(ab, rx_tid, HAL_REO_CMD_FLUSH_CACHE, &cmd, ath11k_dp_reo_cmd_free); @@ -259,7 +259,7 @@ Signed-off-by: Tamizh Chelvam Raja goto free_desc; } else if (status != HAL_REO_CMD_SUCCESS) { /* Shouldn't happen! Cleanup in case of other failure? */ -@@ -815,6 +862,29 @@ static void ath11k_dp_rx_tid_del_func(st +@@ -780,6 +827,29 @@ static void ath11k_dp_rx_tid_del_func(st return; } @@ -289,7 +289,7 @@ Signed-off-by: Tamizh Chelvam Raja elem = kzalloc(sizeof(*elem), GFP_ATOMIC); if (!elem) goto free_desc; -@@ -832,13 +902,20 @@ static void ath11k_dp_rx_tid_del_func(st +@@ -797,13 +867,20 @@ static void ath11k_dp_rx_tid_del_func(st if (dp->reo_cmd_cache_flush_count > DP_REO_DESC_FREE_THRESHOLD || time_after(jiffies, elem->ts + msecs_to_jiffies(DP_REO_DESC_FREE_TIMEOUT_MS))) { @@ -314,7 +314,7 @@ Signed-off-by: Tamizh Chelvam Raja } } spin_unlock_bh(&dp->reo_cmd_lock); -@@ -854,34 +931,48 @@ free_desc: +@@ -819,34 +896,48 @@ free_desc: void ath11k_peer_rx_tid_delete(struct ath11k *ar, struct ath11k_peer *peer, u8 tid) { diff --git a/package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch b/package/kernel/mac80211/patches/nss/ath11k/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch similarity index 90% rename from package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch rename to package/kernel/mac80211/patches/nss/ath11k/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch index 7b3df32c05..df9fb62bcd 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/376-ath11k-Add-nss-event-handler-support-for-link-desc.patch @@ -16,7 +16,7 @@ Signed-off-by: Tamizh Chelvam Raja --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -72,6 +72,43 @@ static void ath11k_nss_wifili_stats_sync +@@ -101,6 +101,43 @@ static void ath11k_nss_wifili_stats_sync spin_unlock_bh(&ab->base_lock); } @@ -60,9 +60,9 @@ Signed-off-by: Tamizh Chelvam Raja static void ath11k_nss_get_peer_stats(struct ath11k_base *ab, struct nss_wifili_peer_stats *stats) { struct ath11k_peer *peer; -@@ -307,6 +344,10 @@ void ath11k_nss_wifili_event_receive(str - case NSS_WIFILI_TID_REOQ_SETUP_MSG: - /* TODO setup tidq */ +@@ -369,6 +406,10 @@ void ath11k_nss_wifili_event_receive(str + ath11k_dbg(ab, ATH11K_DBG_NSS_MESH, "nss wifili mesh capability response %d\n", + ab->nss.mesh_nss_offload_enabled); break; + case NSS_WIFILI_LINK_DESC_INFO_MSG: + ath11k_nss_wifili_link_desc_return(ab, diff --git a/package/kernel/mac80211/patches/nss/ath11k/401-ath11k-Fix-mutex-dead-lock-and-q6-dump-crash.patch b/package/kernel/mac80211/patches/nss/ath11k/401-ath11k-Fix-mutex-dead-lock-and-q6-dump-crash.patch new file mode 100644 index 0000000000..ceeb15c8cb --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/401-ath11k-Fix-mutex-dead-lock-and-q6-dump-crash.patch @@ -0,0 +1,59 @@ +From 0a30d8c3d51d798b50bd792aa49e6a5b5ad14183 Mon Sep 17 00:00:00 2001 +From: Rajat Soni +Date: Wed, 12 Apr 2023 18:06:54 +0530 +Subject: [PATCH] ath11k: Fix mutex dead lock and q6 dump crash + +Issue 1: +Currently for HOST_DDR_REGION_TYPE memory, we are facing crash +because target memory virtual address (vaddr) is NULL. We are +not assigning any value to vaddr. + +Issue 2: +In ath11k_mac_op_start we are using mutex lock and waiting for +waiting for completion of ab->reconfigure_complete. +Before completing ab->reconfigure_complete in function +ath11k_core_reconfigure_on_crash, we are again trying +to get mutex lock in ath11k_spectral_deinit. This results +in dead lock. + +Due to these two issue during SSR case fw recovery pdev +is not recovered properly. + +To resolve these two issues: +Issue1: +During ath11k_qmi_assign_target_mem_chunk we should assign +ab->qmi.target_mem[idx].vaddr. + +Issue 2: +Unlock mutex lock before waiting for completion of +ab->reconfigure_complete and acquiring lock again. + +Signed-off-by: Rajat Soni +--- + drivers/net/wireless/ath/ath11k/mac.c | 2 ++ + drivers/net/wireless/ath/ath11k/qmi.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -6786,7 +6786,9 @@ static int ath11k_mac_op_start(struct ie + break; + case ATH11K_STATE_RESTARTING: + ar->state = ATH11K_STATE_RESTARTED; ++ mutex_unlock(&ar->conf_mutex); + ath11k_mac_wait_reconfigure(ab); ++ mutex_lock(&ar->conf_mutex); + break; + case ATH11K_STATE_RESTARTED: + case ATH11K_STATE_WEDGED: +--- a/drivers/net/wireless/ath/ath11k/qmi.c ++++ b/drivers/net/wireless/ath/ath11k/qmi.c +@@ -2061,6 +2061,8 @@ static int ath11k_qmi_assign_target_mem_ + if (!ab->qmi.target_mem[idx].iaddr) + return -EIO; + ++ ab->qmi.target_mem[idx].vaddr = ab->qmi.target_mem[idx].iaddr; ++ + ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; + host_ddr_sz = ab->qmi.target_mem[i].size; + ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; diff --git a/package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch b/package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch new file mode 100644 index 0000000000..90982924fe --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/453-ath11k-flush-management-frames-to-firmware-before-wa.patch @@ -0,0 +1,38 @@ +From 76482cd32e1053ef6437015d9418636616931213 Mon Sep 17 00:00:00 2001 +From: Hari Chandrakanthan +Date: Thu, 22 Jun 2023 00:45:47 +0530 +Subject: [PATCH] ath11k : flush management frames to firmware before waiting + for tx completion + +warning print "ath11k c000000.wifi: failed to flush mgmt transmit queue 0" +is observed during interface down. + +The management packets are queued in a skb_queue and the skb_queue +is dequeued in the work ar->wmi_mgmt_tx_work. + +In ath11k_mac_flush_tx_complete, before waiting for the tx completion of +all the management frames, we are not ensuring that queued +management frames are flushed to the firmware. + +This causes ar->num_pending_mgmt_tx to be positive and it leads to the +warning print. + +Fix this by flushing all the management frames to firmware before waiting +for the tx completion. + +Signed-off-by: Hari Chandrakanthan +--- + drivers/net/wireless/ath/ath11k/mac.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -8464,6 +8464,8 @@ static int ath11k_mac_flush_tx_complete( + ret = -ETIMEDOUT; + } + ++ flush_work(&ar->wmi_mgmt_tx_work); ++ + time_left = wait_event_timeout(ar->txmgmt_empty_waitq, + (atomic_read(&ar->num_pending_mgmt_tx) == 0), + ATH11K_FLUSH_TIMEOUT); diff --git a/package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch b/package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch new file mode 100644 index 0000000000..510fbc2448 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/456-wifi-ath11k-Advertise-TX_QUEUE-mac-hw-flag.patch @@ -0,0 +1,23 @@ +From dbba58c4f45aecaf2c55a1b2d3500878b86cd8ef Mon Sep 17 00:00:00 2001 +From: Yuvasree Sivasankaran +Date: Mon, 11 Dec 2023 16:02:25 +0530 +Subject: [PATCH] wifi: ath11k: Advertise TX_QUEUE mac hw flag + +To avoid tx queuing in mac80211, advertise TX_QUEUE mac hw flag +which enable tx queuing in driver and avoid performance degradation. + +Signed-off-by: Yuvasree Sivasankaran +--- + drivers/net/wireless/ath/ath11k/mac.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -10141,6 +10141,7 @@ static int __ath11k_mac_register(struct + ieee80211_hw_set(ar->hw, QUEUE_CONTROL); + ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG); + ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK); ++ ieee80211_hw_set(ar->hw, HAS_TX_QUEUE); + + if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) { + ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch b/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-memset-of-ppdu-info-for-next-skb.patch similarity index 86% rename from package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch rename to package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-memset-of-ppdu-info-for-next-skb.patch index 28b4fdf646..21a92296da 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-830-ath11k-Avoiding-memset-of-ppdu-info-for-next-skb.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/457-wifi-ath11k-Avoid-memset-of-ppdu-info-for-next-skb.patch @@ -48,7 +48,7 @@ Signed-off-by: Yuvasree Sivasankaran --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -6210,7 +6210,9 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6089,7 +6089,9 @@ int ath11k_dp_rx_process_mon_status(stru if (!num_buffs_reaped) goto exit; @@ -59,7 +59,7 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; while ((skb = __skb_dequeue(&skb_list))) { -@@ -6228,7 +6230,6 @@ int ath11k_dp_rx_process_mon_status(stru +@@ -6107,7 +6109,6 @@ int ath11k_dp_rx_process_mon_status(stru if (log_type != ATH11K_PKTLOG_TYPE_INVALID) trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz); @@ -67,21 +67,21 @@ Signed-off-by: Yuvasree Sivasankaran ppdu_info->peer_id = HAL_INVALID_PEERID; hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb); -@@ -6244,6 +6245,7 @@ int ath11k_dp_rx_process_mon_status(stru - if (ppdu_info->peer_id == HAL_INVALID_PEERID || - hal_status != HAL_RX_MON_STATUS_PPDU_DONE) { +@@ -6135,6 +6136,7 @@ int ath11k_dp_rx_process_mon_status(stru + if ((ppdu_info->peer_id == HAL_INVALID_PEERID || + hal_status != HAL_RX_MON_STATUS_PPDU_DONE)) { dev_kfree_skb_any(skb); + ppdu_info->ppdu_continuation = true; continue; } - + rcu_read_lock(); --- a/drivers/net/wireless/ath/ath11k/hal_rx.h +++ b/drivers/net/wireless/ath/ath11k/hal_rx.h -@@ -220,6 +220,7 @@ struct hal_rx_mon_ppdu_info { - char rssi_chain[8][8]; +@@ -221,6 +221,7 @@ struct hal_rx_mon_ppdu_info { u32 num_users; u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; -+ bool ppdu_continuation; struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS]; ++ bool ppdu_continuation; }; + #define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30) diff --git a/package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch b/package/kernel/mac80211/patches/nss/ath11k/458-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch similarity index 88% rename from package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch rename to package/kernel/mac80211/patches/nss/ath11k/458-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch index 10c3928809..88903faddf 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/906-456-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/458-wifi-ath11k-Add-support-to-send-the-QoS-Null-Data-fr.patch @@ -18,14 +18,13 @@ Signed-off-by: Karthikeyan Periyasamy --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -209,7 +209,9 @@ tcl_ring_sel: +@@ -221,7 +221,8 @@ tcl_ring_sel: switch (ti.encap_type) { case HAL_TCL_ENCAP_TYPE_NATIVE_WIFI: - if (arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) + if ((arvif->vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) && -+ (skb->protocol == cpu_to_be16(ETH_P_PAE) || -+ ieee80211_is_qos_nullfunc(hdr->frame_control))) ++ ieee80211_is_qos_nullfunc(hdr->frame_control)) is_diff_encap = true; else ath11k_dp_tx_encap_nwifi(skb); diff --git a/package/kernel/mac80211/patches/nss/ath11k/669-ath11k-change-dma_map_single-to-virt_to_phys-in-rx-r.patch b/package/kernel/mac80211/patches/nss/ath11k/669-ath11k-change-dma_map_single-to-virt_to_phys-in-rx-r.patch new file mode 100644 index 0000000000..06cee635f3 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/669-ath11k-change-dma_map_single-to-virt_to_phys-in-rx-r.patch @@ -0,0 +1,66 @@ +From cd0401a0fe82b5f9c31016d11dcc99d9fa4be96d Mon Sep 17 00:00:00 2001 +From: Balamurugan Selvarajan +Date: Wed, 14 Sep 2022 17:12:20 +0530 +Subject: [PATCH] ath11k: Skip cache invalidation in rx replenish + +In ath11k_dp_rxbufs_replenish() the descriptors are updated with +new skb physical address. currently physical address is obtained +using dma_map_single() this api additionally invalidates the cache +lines which is not required in replenish(). This consumes CPU cycles. +In the Rx data path, the desc->skb memory is invalidated before +reading from the memory. So, replace dmap_map_single() with +dma_map_single_attrs(DMA_ATTR_SKIP_CPU_SYNC). This reduces CPU usage by 7%. + +perf top with dma_map_single() +============================= + 24.99% [kernel] [k] __pi___inval_dcache_area + 14.56% [ath11k] [k] ath11k_dp_process_rx + 8.24% [qca_nss_dp] [k] edma_tx_ring_xmit + 5.22% [kernel] [k] dmac_clean_range_no_dsb + 4.26% [kernel] [k] __dma_clean_area_no_dsb + 4.22% [qca_nss_sfe] [k] sfe_recv + 3.90% [kernel] [k] skb_recycler_alloc + 3.87% [kernel] [k] __local_bh_enable_ip + +perf top with dma_map_single_attrs with DMA_ATTR_SKIP_CPU_SYNC +============================================================= + 17.07% [kernel] [k] __pi___inval_dcache_area + 15.53% [ath11k] [k] ath11k_dp_process_rx + 9.03% [qca_nss_dp] [k] edma_tx_ring_xmit + 5.62% [kernel] [k] dmac_clean_range_no_dsb + 5.41% [kernel] [k] skb_recycler_alloc + 4.68% [qca_nss_sfe] [k] sfe_recv + 4.64% [kernel] [k] __dma_clean_area_no_dsb + 3.88% [kernel] [k] __local_bh_enable_ip + +Signed-off-by: Balamurugan Selvarajan +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -392,9 +392,9 @@ int ath11k_dp_rxbufs_replenish(struct at + skb->data); + } + +- paddr = dma_map_single(ab->dev, skb->data, +- skb->len + skb_tailroom(skb), +- DMA_FROM_DEVICE); ++ paddr = dma_map_single_attrs(ab->dev, skb->data, ++ skb->len + skb_tailroom(skb), ++ DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); + if (dma_mapping_error(ab->dev, paddr)) + goto fail_free_skb; + +@@ -430,8 +430,8 @@ fail_idr_remove: + idr_remove(&rx_ring->bufs_idr, buf_id); + spin_unlock_bh(&rx_ring->idr_lock); + fail_dma_unmap: +- dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb), +- DMA_FROM_DEVICE); ++ dma_unmap_single_attrs(ab->dev, paddr, skb->len + skb_tailroom(skb), ++ DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); + fail_free_skb: + dev_kfree_skb_any(skb); + diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-01-wifi-ath11k-remove-invalid-peer-create-logic.patch b/package/kernel/mac80211/patches/nss/ath11k/907-01-wifi-ath11k-remove-invalid-peer-create-logic.patch new file mode 100644 index 0000000000..4d8f9f28e3 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/907-01-wifi-ath11k-remove-invalid-peer-create-logic.patch @@ -0,0 +1,58 @@ +Received: from bqiang-Celadon-RN.qca.qualcomm.com (10.80.80.8) by +From: Baochen Qiang +To: +Subject: [PATCH 1/4] wifi: ath11k: remove invalid peer create logic +Date: Tue, 23 Jan 2024 10:56:57 +0800 + +In ath11k_mac_op_assign_vif_chanctx(), there is a logic to +create peer using ar->mac_addr for a STA vdev. This is invalid +because a STA vdev should have a peer created using AP's +MAC address. Besides, if we run into that logic, it means a peer +has already been created earlier, we should not create it again. +So remove it. + +This is found during code review. + +Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +--- + drivers/net/wireless/ath/ath11k/mac.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -8218,7 +8218,6 @@ ath11k_mac_op_assign_vif_chanctx(struct + struct ath11k_base *ab = ar->ab; + struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); + int ret; +- struct peer_create_params param; + + mutex_lock(&ar->conf_mutex); + +@@ -8241,21 +8240,6 @@ ath11k_mac_op_assign_vif_chanctx(struct + goto out; + } + +- if (ab->hw_params.vdev_start_delay && +- arvif->vdev_type != WMI_VDEV_TYPE_AP && +- arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { +- param.vdev_id = arvif->vdev_id; +- param.peer_type = WMI_PEER_TYPE_DEFAULT; +- param.peer_addr = ar->mac_addr; +- +- ret = ath11k_peer_create(ar, arvif, NULL, ¶m); +- if (ret) { +- ath11k_warn(ab, "failed to create peer after vdev start delay: %d", +- ret); +- goto out; +- } +- } +- + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + ret = ath11k_mac_monitor_start(ar); + if (ret) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-02-wifi-ath11k-rename-ath11k_start_vdev_delay.patch b/package/kernel/mac80211/patches/nss/ath11k/907-02-wifi-ath11k-rename-ath11k_start_vdev_delay.patch new file mode 100644 index 0000000000..7d04e371ed --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/907-02-wifi-ath11k-rename-ath11k_start_vdev_delay.patch @@ -0,0 +1,52 @@ +From: Baochen Qiang +To: +Subject: [PATCH 2/4] wifi: ath11k: rename ath11k_start_vdev_delay() +Date: Tue, 23 Jan 2024 10:56:58 +0800 + +Rename ath11k_start_vdev_delay() as ath11k_mac_start_vdev_delay() +to follow naming convention. + +Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +--- + drivers/net/wireless/ath/ath11k/mac.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -256,8 +256,8 @@ static const u32 ath11k_smps_map[] = { + [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, + }; + +-static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif); ++static int ath11k_mac_start_vdev_delay(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif); + + enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) + { +@@ -5314,7 +5314,7 @@ static int ath11k_mac_station_add(struct + if (ab->hw_params.vdev_start_delay && + !arvif->is_started && + arvif->vdev_type != WMI_VDEV_TYPE_AP) { +- ret = ath11k_start_vdev_delay(ar->hw, vif); ++ ret = ath11k_mac_start_vdev_delay(ar->hw, vif); + if (ret) { + ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); + goto free_tx_stats; +@@ -8161,8 +8161,8 @@ unlock: + mutex_unlock(&ar->conf_mutex); + } + +-static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif) ++static int ath11k_mac_start_vdev_delay(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) + { + struct ath11k *ar = hw->priv; + struct ath11k_base *ab = ar->ab; diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-03-wifi-ath11k-avoid-forward-declaration-of-ath11k_mac_start_vdev_delay.patch b/package/kernel/mac80211/patches/nss/ath11k/907-03-wifi-ath11k-avoid-forward-declaration-of-ath11k_mac_start_vdev_delay.patch new file mode 100644 index 0000000000..f928d851a6 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/907-03-wifi-ath11k-avoid-forward-declaration-of-ath11k_mac_start_vdev_delay.patch @@ -0,0 +1,601 @@ +From: Baochen Qiang +To: +Subject: [PATCH 3/4] wifi: ath11k: avoid forward declaration of + ath11k_mac_start_vdev_delay() +Date: Tue, 23 Jan 2024 10:56:59 +0800 + +Currently ath11k_mac_start_vdev_delay() needs a forward declaration because +it is defined after where it is called. Avoid this by re-arranging +ath11k_mac_station_add() and ath11k_mac_op_sta_state(). + +No functional changes. Compile tested only. + +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +--- + drivers/net/wireless/ath/ath11k/mac.c | 459 +++++++++++++------------- + 1 file changed, 228 insertions(+), 231 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -256,9 +256,6 @@ static const u32 ath11k_smps_map[] = { + [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, + }; + +-static int ath11k_mac_start_vdev_delay(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif); +- + enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy) + { + enum nl80211_he_ru_alloc ret; +@@ -5244,100 +5241,6 @@ static void ath11k_mac_dec_num_stations( + ar->num_stations--; + } + +-static int ath11k_mac_station_add(struct ath11k *ar, +- struct ieee80211_vif *vif, +- struct ieee80211_sta *sta) +-{ +- struct ath11k_base *ab = ar->ab; +- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); +- struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); +- struct peer_create_params peer_param; +- int ret; +- +- lockdep_assert_held(&ar->conf_mutex); +- +- ret = ath11k_mac_inc_num_stations(arvif, sta); +- if (ret) { +- ath11k_warn(ab, "refusing to associate station: too many connected already (%d)\n", +- ar->max_num_stations); +- goto exit; +- } +- +- arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL); +- if (!arsta->rx_stats) { +- ret = -ENOMEM; +- goto dec_num_station; +- } +- +- peer_param.vdev_id = arvif->vdev_id; +- peer_param.peer_addr = sta->addr; +- peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; +- +- ret = ath11k_peer_create(ar, arvif, sta, &peer_param); +- if (ret) { +- ath11k_warn(ab, "Failed to add peer: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- goto free_rx_stats; +- } +- +- ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- +- if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) { +- arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL); +- if (!arsta->tx_stats) { +- ret = -ENOMEM; +- goto free_peer; +- } +- } +- +- if (ieee80211_vif_is_mesh(vif)) { +- ath11k_dbg(ab, ATH11K_DBG_MAC, +- "setting USE_4ADDR for mesh STA %pM\n", sta->addr); +- ret = ath11k_wmi_set_peer_param(ar, sta->addr, +- arvif->vdev_id, +- WMI_PEER_USE_4ADDR, 1); +- if (ret) { +- ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n", +- sta->addr, ret); +- goto free_tx_stats; +- } +- } +- +- ret = ath11k_dp_peer_setup(ar, arvif->vdev_id, sta->addr); +- if (ret) { +- ath11k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n", +- sta->addr, arvif->vdev_id, ret); +- goto free_tx_stats; +- } +- +- if (ab->hw_params.vdev_start_delay && +- !arvif->is_started && +- arvif->vdev_type != WMI_VDEV_TYPE_AP) { +- ret = ath11k_mac_start_vdev_delay(ar->hw, vif); +- if (ret) { +- ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); +- goto free_tx_stats; +- } +- } +- +- ewma_avg_rssi_init(&arsta->avg_rssi); +- return 0; +- +-free_tx_stats: +- kfree(arsta->tx_stats); +- arsta->tx_stats = NULL; +-free_peer: +- ath11k_peer_delete(ar, arvif->vdev_id, sta->addr); +-free_rx_stats: +- kfree(arsta->rx_stats); +- arsta->rx_stats = NULL; +-dec_num_station: +- ath11k_mac_dec_num_stations(arvif, sta); +-exit: +- return ret; +-} +- + static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar, + struct ieee80211_sta *sta) + { +@@ -5393,187 +5296,6 @@ static int ath11k_mac_cfg_dyn_vlan(struc + return ret; + } + +-static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, +- struct ieee80211_vif *vif, +- struct ieee80211_sta *sta, +- enum ieee80211_sta_state old_state, +- enum ieee80211_sta_state new_state) +-{ +- struct ath11k *ar = hw->priv; +- struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); +- struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); +- struct ath11k_peer *peer; +- int ret = 0; +- +- /* cancel must be done outside the mutex to avoid deadlock */ +- if ((old_state == IEEE80211_STA_NONE && +- new_state == IEEE80211_STA_NOTEXIST)) { +- cancel_work_sync(&arsta->update_wk); +- cancel_work_sync(&arsta->set_4addr_wk); +- } +- +- mutex_lock(&ar->conf_mutex); +- +- if (old_state == IEEE80211_STA_NOTEXIST && +- new_state == IEEE80211_STA_NONE) { +- memset(arsta, 0, sizeof(*arsta)); +- arsta->arvif = arvif; +- arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED; +- INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk); +- INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk); +- +- ret = ath11k_mac_station_add(ar, vif, sta); +- if (ret) +- ath11k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- } else if ((old_state == IEEE80211_STA_NONE && +- new_state == IEEE80211_STA_NOTEXIST)) { +- bool skip_peer_delete = ar->ab->hw_params.vdev_start_delay && +- vif->type == NL80211_IFTYPE_STATION; +- +- ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr); +- +- if (!skip_peer_delete) { +- ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr); +- if (ret) +- ath11k_warn(ar->ab, +- "Failed to delete peer: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- else +- ath11k_dbg(ar->ab, +- ATH11K_DBG_MAC, +- "Removed peer: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- } +- +- ath11k_mac_dec_num_stations(arvif, sta); +- mutex_lock(&ar->ab->tbl_mtx_lock); +- spin_lock_bh(&ar->ab->base_lock); +- peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); +- if (skip_peer_delete && peer) { +- peer->sta = NULL; +- } else if (peer && peer->sta == sta) { +- ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", +- vif->addr, arvif->vdev_id); +- ath11k_peer_rhash_delete(ar->ab, peer); +- peer->sta = NULL; +- list_del(&peer->list); +- kfree(peer); +- ar->num_peers--; +- } +- spin_unlock_bh(&ar->ab->base_lock); +- mutex_unlock(&ar->ab->tbl_mtx_lock); +- +- kfree(arsta->tx_stats); +- arsta->tx_stats = NULL; +- +- kfree(arsta->rx_stats); +- arsta->rx_stats = NULL; +- } else if (old_state == IEEE80211_STA_AUTH && +- new_state == IEEE80211_STA_ASSOC && +- (vif->type == NL80211_IFTYPE_AP || +- vif->type == NL80211_IFTYPE_MESH_POINT || +- vif->type == NL80211_IFTYPE_ADHOC)) { +- ret = ath11k_station_assoc(ar, vif, sta, false); +- if (ret) +- ath11k_warn(ar->ab, "Failed to associate station: %pM\n", +- sta->addr); +- +- spin_lock_bh(&ar->data_lock); +- /* Set arsta bw and prev bw */ +- arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); +- arsta->bw_prev = arsta->bw; +- spin_unlock_bh(&ar->data_lock); +- +- /* Driver should clear the peer keys during mac80211's ref ptr +- * gets cleared in __sta_info_destroy_part2 (trans from +- * IEEE80211_STA_AUTHORIZED to IEEE80211_STA_ASSOC) +- */ +- ret = ath11k_clear_peer_keys(arvif, sta->addr); +- if (ret) { +- ath11k_warn(ar->ab, "failed to clear all peer keys for vdev %i: %d\n", +- arvif->vdev_id, ret); +- return ret; +- } +- } else if (old_state == IEEE80211_STA_ASSOC && +- new_state == IEEE80211_STA_AUTHORIZED) { +- spin_lock_bh(&ar->ab->base_lock); +- +- peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); +- if (peer) +- peer->is_authorized = true; +- +- spin_unlock_bh(&ar->ab->base_lock); +- +- if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) { +- ret = ath11k_wmi_set_peer_param(ar, sta->addr, +- arvif->vdev_id, +- WMI_PEER_AUTHORIZE, +- 1); +- if (ret) +- ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n", +- sta->addr, arvif->vdev_id, ret); +- } else if (ar->ab->nss.enabled && +- vif->type == NL80211_IFTYPE_AP_VLAN && +- !arsta->use_4addr_set) { +- +- if (ar->state == ATH11K_STATE_RESTARTED) { +- /* During ieee80211_reconfig(), at this point, nss ext vdev peer is not +- * authorized. Hence ath11k_mac_cfg_dyn_vlan() will return error. We save +- * the state vars here and use it later once nss ext vdev is authorized +- * in ath11k_mac_op_set_key() */ +- struct ath11k_dyn_vlan_cfg *ar_dyn_vlan_cfg; +- ar_dyn_vlan_cfg = kzalloc(sizeof(*ar_dyn_vlan_cfg), GFP_ATOMIC); +- +- if (!ar_dyn_vlan_cfg) { +- ath11k_warn(ar->ab, "failed to save state for dynamic AP_VLAN configuration (%d)", +- -ENOSPC); +- } else { +- INIT_LIST_HEAD(&ar_dyn_vlan_cfg->cfg_list); +- ar_dyn_vlan_cfg->arvif = arvif; +- ar_dyn_vlan_cfg->sta = sta; +- /* save it to arvif (AP_VLAN) list */ +- list_add_tail(&ar_dyn_vlan_cfg->cfg_list, &arvif->dyn_vlan_cfg); +- } +- } else { +- ret = ath11k_mac_cfg_dyn_vlan(ar->ab, arvif, sta); +- if (ret) +- ath11k_warn(ar->ab, "failed to cfg dyn vlan for peer %pM: %d\n", +- sta->addr, ret); +- } +- } +- } else if (old_state == IEEE80211_STA_AUTHORIZED && +- new_state == IEEE80211_STA_ASSOC) { +- +- spin_lock_bh(&ar->ab->base_lock); +- peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); +- if (peer) +- peer->is_authorized = false; +- spin_unlock_bh(&ar->ab->base_lock); +- } else if (old_state == IEEE80211_STA_AUTHORIZED && +- new_state == IEEE80211_STA_ASSOC) { +- spin_lock_bh(&ar->ab->base_lock); +- +- peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); +- if (peer) +- peer->is_authorized = false; +- +- spin_unlock_bh(&ar->ab->base_lock); +- } else if (old_state == IEEE80211_STA_ASSOC && +- new_state == IEEE80211_STA_AUTH && +- (vif->type == NL80211_IFTYPE_AP || +- vif->type == NL80211_IFTYPE_MESH_POINT || +- vif->type == NL80211_IFTYPE_ADHOC)) { +- ret = ath11k_station_disassoc(ar, vif, sta); +- if (ret) +- ath11k_warn(ar->ab, "Failed to disassociate station: %pM\n", +- sta->addr); +- } +- +- mutex_unlock(&ar->conf_mutex); +- return ret; +-} +- + static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +@@ -9738,6 +9460,281 @@ ath11k_mac_op_config_mesh_offload_path(s + } + #endif + ++static int ath11k_mac_station_add(struct ath11k *ar, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); ++ struct peer_create_params peer_param; ++ int ret; ++ ++ lockdep_assert_held(&ar->conf_mutex); ++ ++ ret = ath11k_mac_inc_num_stations(arvif, sta); ++ if (ret) { ++ ath11k_warn(ab, "refusing to associate station: too many connected already (%d)\n", ++ ar->max_num_stations); ++ goto exit; ++ } ++ ++ arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL); ++ if (!arsta->rx_stats) { ++ ret = -ENOMEM; ++ goto dec_num_station; ++ } ++ ++ peer_param.vdev_id = arvif->vdev_id; ++ peer_param.peer_addr = sta->addr; ++ peer_param.peer_type = WMI_PEER_TYPE_DEFAULT; ++ ++ ret = ath11k_peer_create(ar, arvif, sta, &peer_param); ++ if (ret) { ++ ath11k_warn(ab, "Failed to add peer: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ goto free_rx_stats; ++ } ++ ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ ++ if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) { ++ arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL); ++ if (!arsta->tx_stats) { ++ ret = -ENOMEM; ++ goto free_peer; ++ } ++ } ++ ++ if (ieee80211_vif_is_mesh(vif)) { ++ ath11k_dbg(ab, ATH11K_DBG_MAC, ++ "setting USE_4ADDR for mesh STA %pM\n", sta->addr); ++ ret = ath11k_wmi_set_peer_param(ar, sta->addr, ++ arvif->vdev_id, ++ WMI_PEER_USE_4ADDR, 1); ++ if (ret) { ++ ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n", ++ sta->addr, ret); ++ goto free_tx_stats; ++ } ++ } ++ ++ ret = ath11k_dp_peer_setup(ar, arvif->vdev_id, sta->addr); ++ if (ret) { ++ ath11k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n", ++ sta->addr, arvif->vdev_id, ret); ++ goto free_tx_stats; ++ } ++ ++ if (ab->hw_params.vdev_start_delay && ++ !arvif->is_started && ++ arvif->vdev_type != WMI_VDEV_TYPE_AP) { ++ ret = ath11k_mac_start_vdev_delay(ar->hw, vif); ++ if (ret) { ++ ath11k_warn(ab, "failed to delay vdev start: %d\n", ret); ++ goto free_tx_stats; ++ } ++ } ++ ++ ewma_avg_rssi_init(&arsta->avg_rssi); ++ return 0; ++ ++free_tx_stats: ++ kfree(arsta->tx_stats); ++ arsta->tx_stats = NULL; ++free_peer: ++ ath11k_peer_delete(ar, arvif->vdev_id, sta->addr); ++free_rx_stats: ++ kfree(arsta->rx_stats); ++ arsta->rx_stats = NULL; ++dec_num_station: ++ ath11k_mac_dec_num_stations(arvif, sta); ++exit: ++ return ret; ++} ++ ++static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta, ++ enum ieee80211_sta_state old_state, ++ enum ieee80211_sta_state new_state) ++{ ++ struct ath11k *ar = hw->priv; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); ++ struct ath11k_peer *peer; ++ int ret = 0; ++ ++ /* cancel must be done outside the mutex to avoid deadlock */ ++ if ((old_state == IEEE80211_STA_NONE && ++ new_state == IEEE80211_STA_NOTEXIST)) { ++ cancel_work_sync(&arsta->update_wk); ++ cancel_work_sync(&arsta->set_4addr_wk); ++ } ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (old_state == IEEE80211_STA_NOTEXIST && ++ new_state == IEEE80211_STA_NONE) { ++ memset(arsta, 0, sizeof(*arsta)); ++ arsta->arvif = arvif; ++ arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED; ++ INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk); ++ INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk); ++ ++ ret = ath11k_mac_station_add(ar, vif, sta); ++ if (ret) ++ ath11k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ } else if ((old_state == IEEE80211_STA_NONE && ++ new_state == IEEE80211_STA_NOTEXIST)) { ++ bool skip_peer_delete = ar->ab->hw_params.vdev_start_delay && ++ vif->type == NL80211_IFTYPE_STATION; ++ ++ ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr); ++ ++ if (!skip_peer_delete) { ++ ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr); ++ if (ret) ++ ath11k_warn(ar->ab, ++ "Failed to delete peer: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ else ++ ath11k_dbg(ar->ab, ++ ATH11K_DBG_MAC, ++ "Removed peer: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ } ++ ++ ath11k_mac_dec_num_stations(arvif, sta); ++ mutex_lock(&ar->ab->tbl_mtx_lock); ++ spin_lock_bh(&ar->ab->base_lock); ++ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); ++ if (skip_peer_delete && peer) { ++ peer->sta = NULL; ++ } else if (peer && peer->sta == sta) { ++ ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", ++ vif->addr, arvif->vdev_id); ++ ath11k_peer_rhash_delete(ar->ab, peer); ++ peer->sta = NULL; ++ list_del(&peer->list); ++ kfree(peer); ++ ar->num_peers--; ++ } ++ spin_unlock_bh(&ar->ab->base_lock); ++ mutex_unlock(&ar->ab->tbl_mtx_lock); ++ ++ kfree(arsta->tx_stats); ++ arsta->tx_stats = NULL; ++ ++ kfree(arsta->rx_stats); ++ arsta->rx_stats = NULL; ++ } else if (old_state == IEEE80211_STA_AUTH && ++ new_state == IEEE80211_STA_ASSOC && ++ (vif->type == NL80211_IFTYPE_AP || ++ vif->type == NL80211_IFTYPE_MESH_POINT || ++ vif->type == NL80211_IFTYPE_ADHOC)) { ++ ret = ath11k_station_assoc(ar, vif, sta, false); ++ if (ret) ++ ath11k_warn(ar->ab, "Failed to associate station: %pM\n", ++ sta->addr); ++ ++ spin_lock_bh(&ar->data_lock); ++ /* Set arsta bw and prev bw */ ++ arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta); ++ arsta->bw_prev = arsta->bw; ++ spin_unlock_bh(&ar->data_lock); ++ ++ /* Driver should clear the peer keys during mac80211's ref ptr ++ * gets cleared in __sta_info_destroy_part2 (trans from ++ * IEEE80211_STA_AUTHORIZED to IEEE80211_STA_ASSOC) ++ */ ++ ret = ath11k_clear_peer_keys(arvif, sta->addr); ++ if (ret) { ++ ath11k_warn(ar->ab, "failed to clear all peer keys for vdev %i: %d\n", ++ arvif->vdev_id, ret); ++ return ret; ++ } ++ } else if (old_state == IEEE80211_STA_ASSOC && ++ new_state == IEEE80211_STA_AUTHORIZED) { ++ spin_lock_bh(&ar->ab->base_lock); ++ ++ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); ++ if (peer) ++ peer->is_authorized = true; ++ ++ spin_unlock_bh(&ar->ab->base_lock); ++ ++ if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) { ++ ret = ath11k_wmi_set_peer_param(ar, sta->addr, ++ arvif->vdev_id, ++ WMI_PEER_AUTHORIZE, ++ 1); ++ if (ret) ++ ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n", ++ sta->addr, arvif->vdev_id, ret); ++ } else if (ar->ab->nss.enabled && ++ vif->type == NL80211_IFTYPE_AP_VLAN && ++ !arsta->use_4addr_set) { ++ ++ if (ar->state == ATH11K_STATE_RESTARTED) { ++ /* During ieee80211_reconfig(), at this point, nss ext vdev peer is not ++ * authorized. Hence ath11k_mac_cfg_dyn_vlan() will return error. We save ++ * the state vars here and use it later once nss ext vdev is authorized ++ * in ath11k_mac_op_set_key() */ ++ struct ath11k_dyn_vlan_cfg *ar_dyn_vlan_cfg; ++ ar_dyn_vlan_cfg = kzalloc(sizeof(*ar_dyn_vlan_cfg), GFP_ATOMIC); ++ ++ if (!ar_dyn_vlan_cfg) { ++ ath11k_warn(ar->ab, "failed to save state for dynamic AP_VLAN configuration (%d)", ++ -ENOSPC); ++ } else { ++ INIT_LIST_HEAD(&ar_dyn_vlan_cfg->cfg_list); ++ ar_dyn_vlan_cfg->arvif = arvif; ++ ar_dyn_vlan_cfg->sta = sta; ++ /* save it to arvif (AP_VLAN) list */ ++ list_add_tail(&ar_dyn_vlan_cfg->cfg_list, &arvif->dyn_vlan_cfg); ++ } ++ } else { ++ ret = ath11k_mac_cfg_dyn_vlan(ar->ab, arvif, sta); ++ if (ret) ++ ath11k_warn(ar->ab, "failed to cfg dyn vlan for peer %pM: %d\n", ++ sta->addr, ret); ++ } ++ } ++ } else if (old_state == IEEE80211_STA_AUTHORIZED && ++ new_state == IEEE80211_STA_ASSOC) { ++ ++ spin_lock_bh(&ar->ab->base_lock); ++ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); ++ if (peer) ++ peer->is_authorized = false; ++ spin_unlock_bh(&ar->ab->base_lock); ++ } else if (old_state == IEEE80211_STA_AUTHORIZED && ++ new_state == IEEE80211_STA_ASSOC) { ++ spin_lock_bh(&ar->ab->base_lock); ++ ++ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); ++ if (peer) ++ peer->is_authorized = false; ++ ++ spin_unlock_bh(&ar->ab->base_lock); ++ } else if (old_state == IEEE80211_STA_ASSOC && ++ new_state == IEEE80211_STA_AUTH && ++ (vif->type == NL80211_IFTYPE_AP || ++ vif->type == NL80211_IFTYPE_MESH_POINT || ++ vif->type == NL80211_IFTYPE_ADHOC)) { ++ ret = ath11k_station_disassoc(ar, vif, sta); ++ if (ret) ++ ath11k_warn(ar->ab, "Failed to disassociate station: %pM\n", ++ sta->addr); ++ } ++ ++ mutex_unlock(&ar->conf_mutex); ++ return ret; ++} ++ + static const struct ieee80211_ops ath11k_ops = { + .tx = ath11k_mac_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, diff --git a/package/kernel/mac80211/patches/nss/ath11k/907-04-wifi-ath11k-fix-connection-failure-due-to-unexpected-peer-delete.patch b/package/kernel/mac80211/patches/nss/ath11k/907-04-wifi-ath11k-fix-connection-failure-due-to-unexpected-peer-delete.patch new file mode 100644 index 0000000000..010825fd16 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/907-04-wifi-ath11k-fix-connection-failure-due-to-unexpected-peer-delete.patch @@ -0,0 +1,257 @@ +From: Baochen Qiang +To: +Subject: [PATCH 4/4] wifi: ath11k: fix connection failure due to unexpected + peer delete +Date: Tue, 23 Jan 2024 10:57:00 +0800 + +Currently ath11k_mac_op_unassign_vif_chanctx() deletes peer but +ath11k_mac_op_assign_vif_chanctx() doesn't create it. This results in +connection failure if MAC80211 calls drv_unassign_vif_chanctx() and +drv_assign_vif_chanctx() during AUTH and ASSOC, see below log: + +[ 102.372431] wlan0: authenticated +[ 102.372585] ath11k_pci 0000:01:00.0: wlan0: disabling HT/VHT/HE as WMM/QoS is not supported by the AP +[ 102.372593] ath11k_pci 0000:01:00.0: mac chanctx unassign ptr ffff895084638598 vdev_id 0 +[ 102.372808] ath11k_pci 0000:01:00.0: WMI vdev stop id 0x0 +[ 102.383114] ath11k_pci 0000:01:00.0: vdev stopped for vdev id 0 +[ 102.384689] ath11k_pci 0000:01:00.0: WMI peer delete vdev_id 0 peer_addr 20:e5:2a:21:c4:51 +[ 102.396676] ath11k_pci 0000:01:00.0: htt peer unmap vdev 0 peer 20:e5:2a:21:c4:51 id 3 +[ 102.396711] ath11k_pci 0000:01:00.0: peer delete resp for vdev id 0 addr 20:e5:2a:21:c4:51 +[ 102.396722] ath11k_pci 0000:01:00.0: mac removed peer 20:e5:2a:21:c4:51 vdev 0 after vdev stop +[ 102.396780] ath11k_pci 0000:01:00.0: mac chanctx assign ptr ffff895084639c18 vdev_id 0 +[ 102.400628] wlan0: associate with 20:e5:2a:21:c4:51 (try 1/3) +[ 102.508864] wlan0: associate with 20:e5:2a:21:c4:51 (try 2/3) +[ 102.612815] wlan0: associate with 20:e5:2a:21:c4:51 (try 3/3) +[ 102.720846] wlan0: association with 20:e5:2a:21:c4:51 timed out + +The peer delete logic in ath11k_mac_op_unassign_vif_chanctx() is +introduced by commit b4a0f54156ac ("ath11k: move peer delete after +vdev stop of station for QCA6390 and WCN6855") to fix firmware +crash issue caused by unexpected vdev stop/peer delete sequence. + +Actually for a STA interface peer should be deleted in +ath11k_mac_op_sta_state() when STA's state changes from +IEEE80211_STA_NONE to IEEE80211_STA_NOTEXIST, which also coincides +with current peer creation design that peer is created during +IEEE80211_STA_NOTEXIST -> IEEE80211_STA_NONE transition. So move +peer delete back to ath11k_mac_op_sta_state(), also stop vdev before +deleting peer to fix the firmware crash issue mentioned there. In +this way the connection failure mentioned here is also fixed. + +Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23 +Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 +Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 + +Fixes: b4a0f54156ac ("ath11k: move peer delete after vdev stop of station for QCA6390 and WCN6855") +Signed-off-by: Baochen Qiang +Acked-by: Jeff Johnson +--- + drivers/net/wireless/ath/ath11k/mac.c | 139 ++++++++++++++++---------- + 1 file changed, 85 insertions(+), 54 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -7930,6 +7930,30 @@ static int ath11k_mac_start_vdev_delay(s + return 0; + } + ++static int ath11k_mac_stop_vdev_early(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif) ++{ ++ struct ath11k *ar = hw->priv; ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ int ret; ++ ++ if (WARN_ON(!arvif->is_started)) ++ return -EBUSY; ++ ++ ret = ath11k_mac_vdev_stop(arvif); ++ if (ret) { ++ ath11k_warn(ab, "failed to stop vdev %i: %d\n", ++ arvif->vdev_id, ret); ++ return ret; ++ } ++ ++ arvif->is_started = false; ++ ++ /* TODO: Setup ps and cts/rts protection */ ++ return 0; ++} ++ + static int + ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, +@@ -7974,15 +7998,17 @@ ath11k_mac_op_assign_vif_chanctx(struct + goto out; + } + +- ret = ath11k_mac_vdev_start(arvif, ctx); +- if (ret) { +- ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", +- arvif->vdev_id, vif->addr, +- ctx->def.chan->center_freq, ret); +- goto out; +- } ++ if (!arvif->is_started) { ++ ret = ath11k_mac_vdev_start(arvif, ctx); ++ if (ret) { ++ ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n", ++ arvif->vdev_id, vif->addr, ++ ctx->def.chan->center_freq, ret); ++ goto out; ++ } + +- arvif->is_started = true; ++ arvif->is_started = true; ++ } + + if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && + test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) { +@@ -8022,8 +8048,6 @@ ath11k_mac_op_unassign_vif_chanctx(struc + "chanctx unassign ptr %p vdev_id %i\n", + ctx, arvif->vdev_id); + +- WARN_ON(!arvif->is_started); +- + if (ab->hw_params.vdev_start_delay && + arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + spin_lock_bh(&ab->base_lock); +@@ -8047,24 +8071,13 @@ ath11k_mac_op_unassign_vif_chanctx(struc + return; + } + +- ret = ath11k_mac_vdev_stop(arvif); +- if (ret) +- ath11k_warn(ab, "failed to stop vdev %i: %d\n", +- arvif->vdev_id, ret); +- +- arvif->is_started = false; +- +- if (ab->hw_params.vdev_start_delay && +- arvif->vdev_type == WMI_VDEV_TYPE_STA) { +- ret = ath11k_peer_delete(ar, arvif->vdev_id, arvif->bssid); ++ if (arvif->is_started) { ++ ret = ath11k_mac_vdev_stop(arvif); + if (ret) +- ath11k_warn(ar->ab, +- "failed to delete peer %pM for vdev %d: %d\n", +- arvif->bssid, arvif->vdev_id, ret); +- else +- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, +- "removed peer %pM vdev %d after vdev stop\n", +- arvif->bssid, arvif->vdev_id); ++ ath11k_warn(ab, "failed to stop vdev %i: %d\n", ++ arvif->vdev_id, ret); ++ ++ arvif->is_started = false; + } + + if (ab->hw_params.vdev_start_delay && +@@ -9554,6 +9567,46 @@ exit: + return ret; + } + ++static int ath11k_mac_station_remove(struct ath11k *ar, ++ struct ieee80211_vif *vif, ++ struct ieee80211_sta *sta) ++{ ++ struct ath11k_base *ab = ar->ab; ++ struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); ++ struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta); ++ int ret; ++ ++ if (ab->hw_params.vdev_start_delay && ++ arvif->is_started && ++ arvif->vdev_type != WMI_VDEV_TYPE_AP) { ++ ret = ath11k_mac_stop_vdev_early(ar->hw, vif); ++ if (ret) { ++ ath11k_warn(ab, "failed to do early vdev stop: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr); ++ ++ ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr); ++ if (ret) ++ ath11k_warn(ab, "Failed to delete peer: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ else ++ ath11k_dbg(ab, ATH11K_DBG_MAC, "Removed peer: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); ++ ++ ath11k_mac_dec_num_stations(arvif, sta); ++ ++ kfree(arsta->tx_stats); ++ arsta->tx_stats = NULL; ++ ++ kfree(arsta->rx_stats); ++ arsta->rx_stats = NULL; ++ ++ return ret; ++} ++ + static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, +@@ -9589,31 +9642,15 @@ static int ath11k_mac_op_sta_state(struc + sta->addr, arvif->vdev_id); + } else if ((old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST)) { +- bool skip_peer_delete = ar->ab->hw_params.vdev_start_delay && +- vif->type == NL80211_IFTYPE_STATION; +- +- ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr); +- +- if (!skip_peer_delete) { +- ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr); +- if (ret) +- ath11k_warn(ar->ab, +- "Failed to delete peer: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- else +- ath11k_dbg(ar->ab, +- ATH11K_DBG_MAC, +- "Removed peer: %pM for VDEV: %d\n", +- sta->addr, arvif->vdev_id); +- } ++ ret = ath11k_mac_station_remove(ar, vif, sta); ++ if (ret) ++ ath11k_warn(ar->ab, "Failed to remove station: %pM for VDEV: %d\n", ++ sta->addr, arvif->vdev_id); + +- ath11k_mac_dec_num_stations(arvif, sta); + mutex_lock(&ar->ab->tbl_mtx_lock); + spin_lock_bh(&ar->ab->base_lock); + peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr); +- if (skip_peer_delete && peer) { +- peer->sta = NULL; +- } else if (peer && peer->sta == sta) { ++ if (peer && peer->sta == sta) { + ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n", + vif->addr, arvif->vdev_id); + ath11k_peer_rhash_delete(ar->ab, peer); +@@ -9624,12 +9661,6 @@ static int ath11k_mac_op_sta_state(struc + } + spin_unlock_bh(&ar->ab->base_lock); + mutex_unlock(&ar->ab->tbl_mtx_lock); +- +- kfree(arsta->tx_stats); +- arsta->tx_stats = NULL; +- +- kfree(arsta->rx_stats); +- arsta->rx_stats = NULL; + } else if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC && + (vif->type == NL80211_IFTYPE_AP || +@@ -10202,6 +10233,8 @@ static int __ath11k_mac_register(struct + + wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); + ++ wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); ++ + ar->hw->queues = ATH11K_HW_MAX_QUEUES; + ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN; + ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1; diff --git a/package/kernel/mac80211/patches/nss/ath11k/908-ath11k-make-debugfs-sta-htt-stats-modular.patch b/package/kernel/mac80211/patches/nss/ath11k/908-ath11k-make-debugfs-sta-htt-stats-modular.patch new file mode 100644 index 0000000000..4276e64cc3 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/908-ath11k-make-debugfs-sta-htt-stats-modular.patch @@ -0,0 +1,198 @@ +--- a/drivers/net/wireless/ath/ath11k/Kconfig ++++ b/drivers/net/wireless/ath/ath11k/Kconfig +@@ -80,6 +80,24 @@ config ATH11K_DEBUGFS + + If unsure, say Y to make it easier to debug problems. + ++config ATH11K_DEBUGFS_STA ++ bool "QCA ath11k debugfs STA support" ++ depends on ATH11K_DEBUGFS ++ default n ++ help ++ Enable ath11k debugfs STA support ++ ++ If unsure, say Y to make it easier to debug problems. ++ ++config ATH11K_DEBUGFS_HTT_STATS ++ bool "QCA ath11k debugfs HTT stats support" ++ depends on ATH11K_DEBUGFS ++ default n ++ help ++ Enable ath11k debugfs HTT stats support ++ ++ If unsure, say Y to make it easier to debug problems. ++ + config ATH11K_TRACING + bool "ath11k tracing support" + depends on ATH11K && EVENT_TRACING +--- a/drivers/net/wireless/ath/ath11k/Makefile ++++ b/drivers/net/wireless/ath/ath11k/Makefile +@@ -19,7 +19,9 @@ ath11k-y += core.o \ + hw.o \ + pcic.o + +-ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o ++ath11k-$(CPTCFG_ATH11K_DEBUGFS) += debugfs.o ++ath11k-$(CPTCFG_ATH11K_DEBUGFS_STA) += debugfs_sta.o ++ath11k-$(CPTCFG_ATH11K_DEBUGFS_HTT_STATS) += debugfs_htt_stats.o + ath11k-$(CPTCFG_NL80211_TESTMODE) += testmode.o + ath11k-$(CPTCFG_ATH11K_TRACING) += trace.o + ath11k-$(CPTCFG_ATH11K_THERMAL) += thermal.o +--- a/drivers/net/wireless/ath/ath11k/debugfs.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs.c +@@ -1875,7 +1875,9 @@ int ath11k_debugfs_register(struct ath11 + snprintf(buf, 100, "../../ath11k/%pd2", ar->debug.debugfs_pdev); + debugfs_create_symlink("ath11k", ar->hw->wiphy->debugfsdir, buf); + ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + ath11k_debugfs_htt_stats_init(ar); ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + + ath11k_debugfs_fw_stats_init(ar); + +--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c ++++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c +@@ -11,7 +11,9 @@ + #include "debug.h" + #include "dp_tx.h" + #include "dp_rx.h" ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + #include "debugfs_htt_stats.h" ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + + static inline u32 ath11k_he_tones_in_ru_to_nl80211_he_ru_alloc(u16 ru_tones) + { +@@ -551,6 +553,7 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + static int + ath11k_dbg_sta_open_htt_peer_stats(struct inode *inode, struct file *file) + { +@@ -622,6 +625,7 @@ static const struct file_operations fops + .owner = THIS_MODULE, + .llseek = default_llseek, + }; ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + + static ssize_t ath11k_dbg_sta_write_peer_pktlog(struct file *file, + const char __user *buf, +@@ -906,6 +910,7 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + static ssize_t + ath11k_write_htt_peer_stats_reset(struct file *file, + const char __user *user_buf, +@@ -965,6 +970,7 @@ static const struct file_operations fops + .owner = THIS_MODULE, + .llseek = default_llseek, + }; ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + + static ssize_t ath11k_dbg_sta_read_peer_ps_state(struct file *file, + char __user *user_buf, +@@ -1111,8 +1117,10 @@ void ath11k_debugfs_sta_op_add(struct ie + &fops_reset_rx_stats); + } + ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + debugfs_create_file("htt_peer_stats", 0400, dir, sta, + &fops_htt_peer_stats); ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + + debugfs_create_file("peer_pktlog", 0644, dir, sta, + &fops_peer_pktlog); +@@ -1122,10 +1130,12 @@ void ath11k_debugfs_sta_op_add(struct ie + debugfs_create_file("addba_resp", 0200, dir, sta, &fops_addba_resp); + debugfs_create_file("delba", 0200, dir, sta, &fops_delba); + ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + if (test_bit(WMI_TLV_SERVICE_PER_PEER_HTT_STATS_RESET, + ar->ab->wmi_ab.svc_map)) + debugfs_create_file("htt_peer_stats_reset", 0600, dir, sta, + &fops_htt_peer_stats_reset); ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + + debugfs_create_file("peer_ps_state", 0400, dir, sta, + &fops_peer_ps_state); +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -1723,8 +1723,10 @@ ath11k_update_per_peer_tx_stats(struct a + peer_stats->mu_pos = mu_pos; + peer_stats->ru_tones = arsta->txrate.he_ru_alloc; + ++#ifdef CPTCFG_ATH11K_DEBUGFS_STA + if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) + ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); ++#endif + } + + usr_stats->rate_stats_updated = true; +@@ -2170,7 +2172,9 @@ void ath11k_dp_htt_htc_t2h_msg_handler(s + ath11k_htt_pull_ppdu_stats(ab, skb); + break; + case HTT_T2H_MSG_TYPE_EXT_STATS_CONF: ++#ifdef CPTCFG_ATH11K_DEBUGFS_HTT_STATS + ath11k_debugfs_htt_ext_stats_handler(ab, skb); ++#endif /* CPTCFG_ATH11K_DEBUGFS_HTT_STATS */ + break; + case HTT_T2H_MSG_TYPE_PKTLOG: + ath11k_htt_pktlog(ab, skb); +--- a/drivers/net/wireless/ath/ath11k/dp_tx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c +@@ -7,7 +7,9 @@ + #include "core.h" + #include "dp_tx.h" + #include "debug.h" ++#ifdef CPTCFG_ATH11K_DEBUGFS_STA + #include "debugfs_sta.h" ++#endif + #include "hw.h" + #include "peer.h" + #include "mac.h" +@@ -550,7 +552,9 @@ static void ath11k_dp_tx_cache_peer_stat + void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts) + { + struct ath11k_base *ab = ar->ab; ++#ifdef CPTCFG_ATH11K_DEBUGFS_STA + struct ath11k_per_peer_tx_stats *peer_stats = &ar->cached_stats; ++#endif + enum hal_tx_rate_stats_pkt_type pkt_type; + enum hal_tx_rate_stats_sgi sgi; + enum hal_tx_rate_stats_bw bw; +@@ -639,8 +643,10 @@ void ath11k_dp_tx_update_txcompl(struct + ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones); + } + ++#ifdef CPTCFG_ATH11K_DEBUGFS_STA + if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) + ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx); ++#endif + + err_out: + spin_unlock_bh(&ab->base_lock); +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -9811,7 +9811,7 @@ static const struct ieee80211_ops ath11k + .set_wakeup = ath11k_wow_op_set_wakeup, + #endif + +-#ifdef CPTCFG_ATH11K_DEBUGFS ++#ifdef CPTCFG_ATH11K_DEBUGFS_STA + .sta_add_debugfs = ath11k_debugfs_sta_op_add, + #endif + +--- a/local-symbols ++++ b/local-symbols +@@ -176,6 +176,8 @@ ATH11K_MEM_PROFILE_256M= + ATH11K_MEM_PROFILE_512M= + ATH11K_DEBUG= + ATH11K_DEBUGFS= ++ATH11K_DEBUGFS_STA= ++ATH11K_DEBUGFS_HTT_STATS= + ATH11K_TRACING= + ATH11K_SPECTRAL= + ATH11K_THERMAL= diff --git a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch b/package/kernel/mac80211/patches/nss/ath11k/999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch similarity index 77% rename from package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch rename to package/kernel/mac80211/patches/nss/ath11k/999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch index 87314bc425..322698f0ea 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/999-233-ath11k-Disable-rx_header-tlv-for-2K-SKB.patch @@ -12,7 +12,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -666,6 +666,7 @@ static ssize_t ath11k_write_extd_rx_stat +@@ -668,6 +668,7 @@ static ssize_t ath11k_write_extd_rx_stat } ar->debug.rx_filter = tlv_filter.rx_filter; @@ -20,7 +20,7 @@ Signed-off-by: Ramya Gnanasekar for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; -@@ -1111,6 +1112,7 @@ static ssize_t ath11k_write_pktlog_filte +@@ -1228,6 +1229,7 @@ static ssize_t ath11k_write_pktlog_filte } /* Clear rx filter set for monitor mode and rx status */ @@ -30,7 +30,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id, --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h -@@ -219,7 +219,8 @@ struct ath11k_pdev_dp { +@@ -237,7 +237,8 @@ struct ath11k_pdev_dp { #define DP_REO_CMD_RING_SIZE 256 #define DP_REO_STATUS_RING_SIZE 2048 #define DP_RXDMA_BUF_RING_SIZE 4096 @@ -40,7 +40,7 @@ Signed-off-by: Ramya Gnanasekar #define DP_RXDMA_ERR_DST_RING_SIZE 1024 #define DP_RXDMA_MON_STATUS_RING_SIZE ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE #define DP_RXDMA_MONITOR_BUF_RING_SIZE ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE -@@ -609,7 +610,7 @@ enum htt_ppdu_stats_tag_type { +@@ -672,7 +673,7 @@ enum htt_stats_internal_ppdu_frametype { * * |31 26|25|24|23 16|15 8|7 0| * |-----------------+----------------+----------------+---------------| @@ -49,7 +49,7 @@ Signed-off-by: Ramya Gnanasekar * |-------------------------------------------------------------------| * | rsvd2 | ring_buffer_size | * |-------------------------------------------------------------------| -@@ -623,6 +624,14 @@ enum htt_ppdu_stats_tag_type { +@@ -686,6 +687,14 @@ enum htt_stats_internal_ppdu_frametype { * |-------------------------------------------------------------------| * | tlv_filter_in_flags | * |-------------------------------------------------------------------| @@ -64,17 +64,19 @@ Signed-off-by: Ramya Gnanasekar * Where: * PS = pkt_swap * SS = status_swap -@@ -636,6 +645,9 @@ enum htt_ppdu_stats_tag_type { +@@ -699,7 +708,10 @@ enum htt_stats_internal_ppdu_frametype { * More details can be got from enum htt_srng_ring_id * b'24 - status_swap: 1 is to swap status TLV * b'25 - pkt_swap: 1 is to swap packet TLV +- * b'26:31 - rsvd1: reserved for future use + * b'26 - rx_offset_valid (OV): flag to indicate rx offsets + * configuration fields are valid + * - * b'26:31 - rsvd1: reserved for future use ++ * b'27:31 - rsvd1: reserved for future use * dword1 - b'0:16 - ring_buffer_size: size of buffers referenced by rx ring, * in byte units. -@@ -665,6 +677,42 @@ enum htt_ppdu_stats_tag_type { + * Valid only for HW_TO_SW_RING and SW_TO_HW_RING +@@ -728,6 +740,42 @@ enum htt_stats_internal_ppdu_frametype { * dword6 - b'0:31 - tlv_filter_in_flags: * Filter in Attention/MPDU/PPDU/Header/User tlvs * Refer to CFG_TLV_FILTER_IN_FLAG defs @@ -117,7 +119,7 @@ Signed-off-by: Ramya Gnanasekar */ #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) -@@ -672,8 +720,16 @@ enum htt_ppdu_stats_tag_type { +@@ -735,8 +783,16 @@ enum htt_stats_internal_ppdu_frametype { #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID GENMASK(23, 16) #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS BIT(24) #define HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS BIT(25) @@ -134,7 +136,7 @@ Signed-off-by: Ramya Gnanasekar enum htt_rx_filter_tlv_flags { HTT_RX_FILTER_TLV_FLAGS_MPDU_START = BIT(0), -@@ -977,6 +1033,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { +@@ -1040,6 +1096,14 @@ enum htt_rx_data_pkt_filter_tlv_flasg3 { HTT_RX_FILTER_TLV_FLAGS_PER_MSDU_HEADER | \ HTT_RX_FILTER_TLV_FLAGS_ATTENTION) @@ -149,7 +151,7 @@ Signed-off-by: Ramya Gnanasekar struct htt_rx_ring_selection_cfg_cmd { u32 info0; u32 info1; -@@ -985,6 +1049,10 @@ struct htt_rx_ring_selection_cfg_cmd { +@@ -1048,6 +1112,10 @@ struct htt_rx_ring_selection_cfg_cmd { u32 pkt_type_en_flags2; u32 pkt_type_en_flags3; u32 rx_filter_tlv; @@ -160,7 +162,7 @@ Signed-off-by: Ramya Gnanasekar } __packed; struct htt_rx_ring_tlv_filter { -@@ -993,6 +1061,14 @@ struct htt_rx_ring_tlv_filter { +@@ -1056,6 +1124,14 @@ struct htt_rx_ring_tlv_filter { u32 pkt_filter_flags1; /* MGMT */ u32 pkt_filter_flags2; /* CTRL */ u32 pkt_filter_flags3; /* DATA */ @@ -177,7 +179,7 @@ Signed-off-by: Ramya Gnanasekar #define HTT_RX_FULL_MON_MODE_CFG_CMD_INFO0_MSG_TYPE GENMASK(7, 0) --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -70,6 +70,12 @@ static inline bool ath11k_dp_rx_h_mpdu_s +@@ -73,6 +73,12 @@ static inline bool ath11k_dp_rx_h_mpdu_s return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); } @@ -190,7 +192,7 @@ Signed-off-by: Ramya Gnanasekar static inline bool ath11k_dp_rx_h_mpdu_start_more_frags(struct ath11k_base *ab, struct sk_buff *skb) { -@@ -306,6 +312,35 @@ static u8 *ath11k_dp_rxdesc_mpdu_start_a +@@ -309,6 +315,35 @@ static u8 *ath11k_dp_rxdesc_mpdu_start_a return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc); } @@ -226,7 +228,7 @@ Signed-off-by: Ramya Gnanasekar static void ath11k_dp_service_mon_ring(struct timer_list *t) { struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer); -@@ -1976,6 +2011,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a +@@ -2389,6 +2424,49 @@ int ath11k_dp_rx_crypto_icv_len(struct a return 0; } @@ -276,7 +278,7 @@ Signed-off-by: Ramya Gnanasekar static void ath11k_dp_rx_h_undecap_nwifi(struct ath11k *ar, struct sk_buff *msdu, u8 *first_hdr, -@@ -1989,7 +2067,8 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2402,7 +2480,8 @@ static void ath11k_dp_rx_h_undecap_nwifi u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; u16 qos_ctl = 0; @@ -286,7 +288,7 @@ Signed-off-by: Ramya Gnanasekar /* copy SA & DA and pull decapped header */ hdr = (struct ieee80211_hdr *)msdu->data; -@@ -1998,7 +2077,7 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2411,7 +2490,7 @@ static void ath11k_dp_rx_h_undecap_nwifi ether_addr_copy(sa, ieee80211_get_SA(hdr)); skb_pull(msdu, ieee80211_hdrlen(hdr->frame_control)); @@ -295,7 +297,7 @@ Signed-off-by: Ramya Gnanasekar /* original 802.11 header is valid for the first msdu * hence we can reuse the same header */ -@@ -2028,16 +2107,23 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2441,16 +2520,23 @@ static void ath11k_dp_rx_h_undecap_nwifi /* copy decap header before overwriting for reuse below */ memcpy(decap_hdr, (uint8_t *)hdr, hdr_len); @@ -324,7 +326,7 @@ Signed-off-by: Ramya Gnanasekar memcpy(skb_push(msdu, IEEE80211_QOS_CTL_LEN), &qos_ctl, IEEE80211_QOS_CTL_LEN); -@@ -2153,6 +2239,20 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2566,6 +2652,20 @@ static void ath11k_dp_rx_h_undecap_eth(s u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; void *rfc1042; @@ -345,7 +347,7 @@ Signed-off-by: Ramya Gnanasekar rfc1042 = ath11k_dp_rx_h_find_rfc1042(ar, msdu, enctype); if (WARN_ON_ONCE(!rfc1042)) -@@ -2181,6 +2281,7 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2594,6 +2694,7 @@ static void ath11k_dp_rx_h_undecap_eth(s memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); @@ -353,7 +355,7 @@ Signed-off-by: Ramya Gnanasekar /* original 802.11 header has a different DA and in * case of 4addr it may also have different SA */ -@@ -2199,6 +2300,7 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2612,6 +2713,7 @@ static void ath11k_dp_rx_h_undecap_snap( size_t hdr_len; u8 l3_pad_bytes; struct hal_rx_desc *rx_desc; @@ -361,7 +363,7 @@ Signed-off-by: Ramya Gnanasekar /* Delivered decapped frame: * [amsdu header] <-- replaced with 802.11 hdr -@@ -2212,6 +2314,11 @@ static void ath11k_dp_rx_h_undecap_snap( +@@ -2625,6 +2727,11 @@ static void ath11k_dp_rx_h_undecap_snap( skb_put(msdu, l3_pad_bytes); skb_pull(msdu, sizeof(struct ath11k_dp_amsdu_subframe_hdr) + l3_pad_bytes); @@ -373,7 +375,7 @@ Signed-off-by: Ramya Gnanasekar hdr = (struct ieee80211_hdr *)first_hdr; hdr_len = ieee80211_hdrlen(hdr->frame_control); -@@ -2608,6 +2715,20 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3098,6 +3205,20 @@ static int ath11k_dp_rx_process_msdu(str goto free_out; } @@ -394,7 +396,7 @@ Signed-off-by: Ramya Gnanasekar rxcb = ATH11K_SKB_RXCB(msdu); rxcb->rx_desc = rx_desc; msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ab, rx_desc); -@@ -2620,8 +2741,9 @@ static int ath11k_dp_rx_process_msdu(str +@@ -3110,8 +3231,9 @@ static int ath11k_dp_rx_process_msdu(str hdr_status = ath11k_dp_rx_h_80211_hdr(ab, rx_desc); ret = -EINVAL; ath11k_warn(ab, "invalid msdu len %u\n", msdu_len); @@ -406,7 +408,7 @@ Signed-off-by: Ramya Gnanasekar ath11k_dbg_dump(ab, ATH11K_DBG_DATA, NULL, "", rx_desc, sizeof(struct hal_rx_desc)); goto free_out; -@@ -3283,6 +3405,7 @@ static int ath11k_dp_rx_h_verify_tkip_mi +@@ -4070,6 +4192,7 @@ static int ath11k_dp_rx_h_verify_tkip_mi hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); hdr_len = ieee80211_hdrlen(hdr->frame_control); @@ -414,7 +416,7 @@ Signed-off-by: Ramya Gnanasekar head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; -@@ -3563,8 +3686,8 @@ static void ath11k_dp_rx_h_sort_frags(st +@@ -4350,8 +4473,8 @@ static void ath11k_dp_rx_h_sort_frags(st static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb) { @@ -424,7 +426,7 @@ Signed-off-by: Ramya Gnanasekar u8 *ehdr; u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; -@@ -3794,8 +3917,9 @@ ath11k_dp_process_rx_err_buf(struct ath1 +@@ -4581,8 +4704,9 @@ ath11k_dp_process_rx_err_buf(struct ath1 if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { hdr_status = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc); ath11k_warn(ar->ab, "invalid msdu leng %u", msdu_len); @@ -436,7 +438,7 @@ Signed-off-by: Ramya Gnanasekar ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc, sizeof(struct hal_rx_desc)); dev_kfree_skb_any(msdu); -@@ -4418,6 +4542,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 +@@ -5207,6 +5331,47 @@ void ath11k_dp_rx_pdev_free(struct ath11 ath11k_dp_rxdma_pdev_buf_free(ar); } @@ -484,7 +486,7 @@ Signed-off-by: Ramya Gnanasekar int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int mac_id) { struct ath11k *ar = ab->pdevs[mac_id].ar; -@@ -4511,6 +4676,12 @@ config_refill_ring: +@@ -5300,6 +5465,12 @@ config_refill_ring: } } @@ -499,7 +501,7 @@ Signed-off-by: Ramya Gnanasekar --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c -@@ -1127,6 +1127,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str +@@ -1263,6 +1263,8 @@ int ath11k_dp_tx_htt_rx_filter_setup(str !!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP)); cmd->info0 |= FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS, !!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)); @@ -508,7 +510,7 @@ Signed-off-by: Ramya Gnanasekar cmd->info1 = FIELD_PREP(HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE, rx_buf_size); -@@ -1136,6 +1138,26 @@ int ath11k_dp_tx_htt_rx_filter_setup(str +@@ -1272,6 +1274,26 @@ int ath11k_dp_tx_htt_rx_filter_setup(str cmd->pkt_type_en_flags3 = tlv_filter->pkt_filter_flags3; cmd->rx_filter_tlv = tlv_filter->rx_filter; @@ -535,7 +537,7 @@ Signed-off-by: Ramya Gnanasekar ret = ath11k_htc_send(&ab->htc, ab->dp.eid, skb); if (ret) goto err_free; -@@ -1214,6 +1236,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c +@@ -1350,6 +1372,7 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c } ring_id = dp->rxdma_mon_buf_ring.refill_buf_ring.ring_id; @@ -557,7 +559,7 @@ Signed-off-by: Ramya Gnanasekar } static bool ath11k_hw_ipq8074_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -@@ -395,26 +399,132 @@ static void ath11k_hw_ipq8074_rx_desc_se +@@ -405,26 +409,132 @@ static void ath11k_hw_ipq8074_rx_desc_se desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); } @@ -696,7 +698,7 @@ Signed-off-by: Ramya Gnanasekar } static bool ath11k_hw_qcn9074_rx_desc_get_first_msdu(struct hal_rx_desc *desc) -@@ -437,7 +547,11 @@ static u8 ath11k_hw_qcn9074_rx_desc_get_ +@@ -447,7 +557,11 @@ static u8 ath11k_hw_qcn9074_rx_desc_get_ static u8 *ath11k_hw_qcn9074_rx_desc_get_hdr_status(struct hal_rx_desc *desc) { @@ -708,7 +710,7 @@ Signed-off-by: Ramya Gnanasekar } static bool ath11k_hw_qcn9074_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -@@ -614,7 +728,11 @@ static u8 ath11k_hw_wcn6855_rx_desc_get_ +@@ -634,7 +748,11 @@ static u8 ath11k_hw_wcn6855_rx_desc_get_ static u8 *ath11k_hw_wcn6855_rx_desc_get_hdr_status(struct hal_rx_desc *desc) { @@ -720,10 +722,107 @@ Signed-off-by: Ramya Gnanasekar } static bool ath11k_hw_wcn6855_rx_desc_encrypt_valid(struct hal_rx_desc *desc) -@@ -956,6 +1074,13 @@ const struct ath11k_hw_ops ipq8074_ops = - .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, +@@ -784,6 +902,96 @@ static u8 *ath11k_hw_wcn6855_rx_desc_mpd + { + return desc->u.wcn6855.mpdu_start.addr2; + } ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++static void ath11k_hw_qcn9074_rx_desc_get_offset(struct htt_rx_ring_tlv_filter *tlv_filter) ++{ ++ tlv_filter->rx_mpdu_end_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_qcn9074, mpdu_end_tag)); ++ tlv_filter->rx_mpdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_qcn9074, mpdu_start_tag)); ++ tlv_filter->rx_msdu_end_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_qcn9074, msdu_end_tag)); ++ tlv_filter->rx_msdu_start_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_qcn9074, msdu_start_tag)); ++ tlv_filter->rx_attn_offset = __le16_to_cpu(offsetof ++ (struct hal_rx_desc_qcn9074, rx_attn_tag)); ++} ++#endif ++ ++static u16 ath11k_hw_qcn9074_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc) ++{ ++ return __le16_to_cpu(desc->u.qcn9074.mpdu_start.frame_ctrl); ++} ++ ++static bool ath11k_hw_qcn9074_rx_desc_dot11_hdr_fields_valid(struct hal_rx_desc *desc) ++{ ++ if ((ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld(desc) && ++ ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid(desc) && ++ (__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR1_VALID) && ++ ath11k_hw_qcn9074_rx_desc_mac_addr2_valid(desc) && ++ (__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR3_VALID) && ++ FIELD_GET((RX_MPDU_START_INFO11_MPDU_DUR_VALID), ++ __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11)))) { ++ return true; ++ } ++ return false; ++} ++ ++static void ath11k_hw_qcn9074_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, ++ struct ieee80211_hdr *hdr) ++{ ++ hdr->frame_control = __le16_to_cpu(desc->u.qcn9074.mpdu_start.frame_ctrl); ++ hdr->duration_id = __le16_to_cpu(desc->u.qcn9074.mpdu_start.duration); ++ ether_addr_copy(hdr->addr1, desc->u.qcn9074.mpdu_start.addr1); ++ ether_addr_copy(hdr->addr2, desc->u.qcn9074.mpdu_start.addr2); ++ ether_addr_copy(hdr->addr3, desc->u.qcn9074.mpdu_start.addr3); ++ if (__le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & ++ RX_MPDU_START_INFO11_MAC_ADDR4_VALID) { ++ ether_addr_copy(hdr->addr4, desc->u.qcn9074.mpdu_start.addr4); ++ } ++ hdr->seq_ctrl = __le16_to_cpu(desc->u.qcn9074.mpdu_start.seq_ctrl); ++} ++ ++static void ath11k_hw_qcn9074_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc, ++ u8 *crypto_hdr, ++ enum hal_encrypt_type enctype) ++{ ++ unsigned int key_id; ++ ++ switch (enctype) { ++ case HAL_ENCRYPT_TYPE_OPEN: ++ return; ++ case HAL_ENCRYPT_TYPE_TKIP_NO_MIC: ++ case HAL_ENCRYPT_TYPE_TKIP_MIC: ++ crypto_hdr[0] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9074.mpdu_start.pn[0]); ++ crypto_hdr[1] = 0; ++ crypto_hdr[2] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9074.mpdu_start.pn[0]); ++ break; ++ case HAL_ENCRYPT_TYPE_CCMP_128: ++ case HAL_ENCRYPT_TYPE_CCMP_256: ++ case HAL_ENCRYPT_TYPE_GCMP_128: ++ case HAL_ENCRYPT_TYPE_AES_GCMP_256: ++ crypto_hdr[0] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9074.mpdu_start.pn[0]); ++ crypto_hdr[1] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9074.mpdu_start.pn[0]); ++ crypto_hdr[2] = 0; ++ break; ++ case HAL_ENCRYPT_TYPE_WEP_40: ++ case HAL_ENCRYPT_TYPE_WEP_104: ++ case HAL_ENCRYPT_TYPE_WEP_128: ++ case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4: ++ case HAL_ENCRYPT_TYPE_WAPI: ++ return; ++ } ++ key_id = FIELD_GET(RX_MPDU_START_INFO12_KEY_ID, ++ __le32_to_cpu(desc->u.qcn9074.mpdu_start.info12)); ++ crypto_hdr[3] = 0x20 | (key_id << 6); ++ crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9074.mpdu_start.pn[0]); ++ crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9074.mpdu_start.pn[0]); ++ crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9074.mpdu_start.pn[1]); ++ crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9074.mpdu_start.pn[1]); ++} + + static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab) + { +@@ -988,6 +1196,13 @@ const struct ath11k_hw_ops ipq8074_ops = .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, +#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + .rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset, +#endif @@ -734,44 +833,60 @@ Signed-off-by: Ramya Gnanasekar }; const struct ath11k_hw_ops ipq6018_ops = { -@@ -1043,6 +1168,8 @@ const struct ath11k_hw_ops qcn9074_ops = - .wmi_init_config = ath11k_init_wmi_config_ipq8074, - .mac_id_to_pdev_id = ath11k_hw_mac_id_to_pdev_id_ipq8074, - .mac_id_to_srng_id = ath11k_hw_mac_id_to_srng_id_ipq8074, -+ .rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid, -+ .rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2, - .tx_mesh_enable = ath11k_hw_qcn9074_tx_mesh_enable, - .rx_desc_get_first_msdu = ath11k_hw_qcn9074_rx_desc_get_first_msdu, - .rx_desc_get_last_msdu = ath11k_hw_qcn9074_rx_desc_get_last_msdu, -@@ -1073,8 +1200,6 @@ const struct ath11k_hw_ops qcn9074_ops = +@@ -1029,6 +1244,13 @@ const struct ath11k_hw_ops ipq6018_ops = + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++ .rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset, ++#endif ++ .rx_desc_get_mpdu_frame_ctl = ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl, ++ .rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid, ++ .rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr, ++ .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, + }; + + const struct ath11k_hw_ops qca6390_ops = { +@@ -1071,6 +1293,13 @@ const struct ath11k_hw_ops qca6390_ops = + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++ .rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset, ++#endif ++ .rx_desc_get_mpdu_frame_ctl = ath11k_hw_ipq8074_rx_desc_get_mpdu_frame_ctl, ++ .rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid, ++ .rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr, ++ .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, + }; + + const struct ath11k_hw_ops qcn9074_ops = { +@@ -1108,10 +1337,17 @@ const struct ath11k_hw_ops qcn9074_ops = .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload, .reo_setup = ath11k_hw_ipq8074_reo_setup, .mpdu_info_get_peerid = ath11k_hw_qcn9074_mpdu_info_get_peerid, - .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, - .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, ++ .rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid, ++ .rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2, .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len, ++#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M ++ .rx_desc_get_offset = ath11k_hw_qcn9074_rx_desc_get_offset, ++#endif ++ .rx_desc_get_mpdu_frame_ctl = ath11k_hw_qcn9074_rx_desc_get_mpdu_frame_ctl, ++ .rx_desc_dot11_hdr_fields_valid = ath11k_hw_qcn9074_rx_desc_dot11_hdr_fields_valid, ++ .rx_desc_get_dot11_hdr = ath11k_hw_qcn9074_rx_desc_get_dot11_hdr, ++ .rx_desc_get_crypto_header = ath11k_hw_qcn9074_rx_desc_get_crypto_hdr, }; + const struct ath11k_hw_ops wcn6855_ops = { --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -22,7 +22,11 @@ +@@ -22,6 +22,11 @@ #define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE 512 #define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 128 #define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 128 -- -+#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 -+/* 256b desc TLV + 4b(rounded) Pad + 30byte max nwifi header + -+ * 18byte mesh hdr + 8byte snap + 1500 eth payload -+ */ -+#define ATH11K_DP_RXDMA_NSS_REFILL_RING_SIZE 1816 - #elif defined(CPTCFG_ATH11K_MEM_PROFILE_512M) - #define TARGET_NUM_VDEVS(ab) 8 - #define TARGET_NUM_PEERS_PDEV(ab) (128 + TARGET_NUM_VDEVS(ab)) -@@ -34,7 +38,11 @@ - #define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE 512 - #define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 128 - #define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 128 -- +#define ATH11K_DP_RXDMA_REFILL_RING_SIZE 2048 +/* 256b desc TLV + 4b(rounded) Pad + 30byte max nwifi header + + * 18byte mesh hdr + 8byte snap + 1500 eth payload @@ -780,7 +895,7 @@ Signed-off-by: Ramya Gnanasekar #else /* Num VDEVS per radio */ #define TARGET_NUM_VDEVS(ab) (ab->hw_params.num_vdevs_peers[ab->qmi.target_mem_mode].num_vdevs) -@@ -47,6 +55,8 @@ +@@ -33,6 +38,8 @@ #define ATH11K_DP_RXDMA_MON_STATUS_RING_SIZE 1024 #define ATH11K_DP_RXDMA_MONITOR_BUF_RING_SIZE 4096 #define ATH11K_DP_RXDMA_MONITOR_DST_RING_SIZE 2048 @@ -789,27 +904,20 @@ Signed-off-by: Ramya Gnanasekar #endif /* Num of peers for Single Radio mode */ -@@ -142,6 +152,8 @@ enum ath11k_bus { - +@@ -129,6 +136,9 @@ enum ath11k_bus { struct hal_rx_desc; struct hal_tcl_data_cmd; + +struct htt_rx_ring_tlv_filter; +enum hal_encrypt_type; - ++ struct ath11k_hw_ring_mask { u8 tx[ATH11K_EXT_IRQ_GRP_NUM_MAX]; -@@ -231,6 +243,7 @@ struct ath11k_hw_params { - const struct ath11k_hw_hal_params *hal_params; - bool supports_dynamic_smps_6ghz; - bool alloc_cacheable_memory; -+ u8 reo_dest_ring_map_shift; - bool supports_rssi_stats; - bool fw_wmi_diag_event; - bool current_cc_support; -@@ -299,6 +312,16 @@ struct ath11k_hw_ops { - bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); + u8 rx_mon_status[ATH11K_EXT_IRQ_GRP_NUM_MAX]; +@@ -287,6 +297,16 @@ struct ath11k_hw_ops { u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); u32 (*get_ring_selector)(struct sk_buff *skb); + u32 (*rx_desc_get_hal_mpdu_len)(struct hal_rx_mpdu_info *mpdu_info); +#ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + void (*rx_desc_get_offset)(struct htt_rx_ring_tlv_filter *tlv_filter); +#endif @@ -825,16 +933,7 @@ Signed-off-by: Ramya Gnanasekar extern const struct ath11k_hw_ops ipq8074_ops; --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -3421,7 +3421,7 @@ static int ath11k_mac_config_obss_pd(str - - static void ath11k_mac_op_nss_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, -- u32 changed) -+ u64 changed) - { - struct ath11k *ar = hw->priv; - struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); -@@ -6340,6 +6340,7 @@ static int ath11k_mac_config_mon_status_ +@@ -6450,6 +6450,7 @@ static int ath11k_mac_config_mon_status_ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar); } @@ -842,15 +941,6 @@ Signed-off-by: Ramya Gnanasekar for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) { ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id; ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, -@@ -9716,8 +9717,6 @@ static int __ath11k_mac_register(struct - wiphy_ext_feature_set(ar->hw->wiphy, - NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); - -- wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); -- - ar->hw->queues = ATH11K_HW_MAX_QUEUES; - ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN; - ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1; --- a/drivers/net/wireless/ath/ath11k/rx_desc.h +++ b/drivers/net/wireless/ath/ath11k/rx_desc.h @@ -1442,9 +1442,11 @@ struct hal_rx_desc_ipq8074 { @@ -889,7 +979,7 @@ Signed-off-by: Ramya Gnanasekar u8 msdu_payload[]; } __packed; -@@ -1502,4 +1508,17 @@ struct hal_rx_desc { +@@ -1507,4 +1513,17 @@ struct hal_rx_desc { #define RU_484 18 #define RU_996 37 @@ -909,7 +999,7 @@ Signed-off-by: Ramya Gnanasekar #endif /* ATH11K_RX_DESC_H */ --- a/drivers/net/wireless/ath/ath11k/nss.c +++ b/drivers/net/wireless/ath/ath11k/nss.c -@@ -1800,7 +1800,7 @@ static int ath11k_nss_init(struct ath11k +@@ -4360,7 +4360,7 @@ static int ath11k_nss_init(struct ath11k /* fill rx parameters to initialize rx context */ wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; diff --git a/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch b/package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch similarity index 85% rename from package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch rename to package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch index 0a7dcf5e84..c95960f2de 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/999-311-ath11k-configure-nss-thread-priority-during-pdev_ini.patch @@ -22,7 +22,7 @@ Signed-off-by: Seevalamuthu Mariappan #include "debug.h" #include "mac.h" -@@ -1782,6 +1783,7 @@ static int ath11k_nss_init(struct ath11k +@@ -4342,6 +4343,7 @@ static int ath11k_nss_init(struct ath11k nss_tx_status_t status; struct ath11k_dp *dp; int i, ret; @@ -30,7 +30,7 @@ Signed-off-by: Seevalamuthu Mariappan dp = &ab->dp; -@@ -1801,6 +1803,8 @@ static int ath11k_nss_init(struct ath11k +@@ -4361,6 +4363,8 @@ static int ath11k_nss_init(struct ath11k /* fill rx parameters to initialize rx context */ wim->wrip.tlv_size = ab->hw_params.hal_desc_sz; wim->wrip.rx_buf_len = DP_RXDMA_NSS_REFILL_RING_SIZE; @@ -39,7 +39,7 @@ Signed-off-by: Seevalamuthu Mariappan /* fill hal srng message */ wim->hssm.dev_base_addr = (u32)ab->mem_pa; -@@ -1977,11 +1981,13 @@ int ath11k_nss_pdev_init(struct ath11k_b +@@ -4549,11 +4553,13 @@ int ath11k_nss_pdev_init(struct ath11k_b struct nss_wifili_msg *wlmsg = NULL; nss_wifili_msg_callback_t msg_cb; nss_tx_status_t status; @@ -54,7 +54,7 @@ Signed-off-by: Seevalamuthu Mariappan dyn_if_type = ath11k_nss_get_dynamic_interface_type(ab); -@@ -2010,6 +2016,15 @@ int ath11k_nss_pdev_init(struct ath11k_b +@@ -4582,6 +4588,15 @@ int ath11k_nss_pdev_init(struct ath11k_b ath11k_dbg(ab, ATH11K_DBG_NSS, "nss pdev init - id:%d init ctxt:%p ifnum:%d\n", ar->pdev->pdev_id, ar->nss.ctx, ar->nss.if_num); @@ -70,7 +70,7 @@ Signed-off-by: Seevalamuthu Mariappan wlmsg = kzalloc(sizeof(struct nss_wifili_msg), GFP_ATOMIC); if (!wlmsg) { ret = -ENOMEM; -@@ -2022,6 +2037,7 @@ int ath11k_nss_pdev_init(struct ath11k_b +@@ -4594,6 +4609,7 @@ int ath11k_nss_pdev_init(struct ath11k_b pdevmsg->lmac_id = ar->lmac_id; pdevmsg->target_pdev_id = ar->pdev->pdev_id; pdevmsg->num_rx_swdesc = WIFILI_RX_DESC_POOL_WEIGHT * DP_RXDMA_BUF_RING_SIZE; @@ -78,7 +78,7 @@ Signed-off-by: Seevalamuthu Mariappan /* Store rxdma ring info to the message */ refill_ring_id = ar->dp.rx_refill_buf_ring.refill_buf_ring.ring_id; -@@ -2315,6 +2331,9 @@ int ath11k_nss_pdev_deinit(struct ath11k +@@ -4887,6 +4903,9 @@ int ath11k_nss_pdev_deinit(struct ath11k /* pdev deinit msg success, dealloc, deregister and return */ ret = 0; @@ -90,7 +90,7 @@ Signed-off-by: Seevalamuthu Mariappan free: --- a/drivers/net/wireless/ath/ath11k/nss.h +++ b/drivers/net/wireless/ath/ath11k/nss.h -@@ -61,6 +61,7 @@ struct hal_rx_user_status; +@@ -70,6 +70,7 @@ struct hal_rx_user_status; /* Init Flags */ #define WIFILI_NSS_CCE_DISABLED 0x1 #define WIFILI_ADDTL_MEM_SEG_SET 0x000000002 @@ -98,9 +98,9 @@ Signed-off-by: Seevalamuthu Mariappan /* ATH11K NSS PEER Info */ /* Host memory allocated for peer info storage in nss */ -@@ -108,6 +109,8 @@ enum ath11k_nss_vdev_cmd { - ATH11K_NSS_WIFI_VDEV_DECAP_TYPE_CMD, - }; +@@ -122,6 +123,8 @@ enum ath11k_nss_vdev_cmd { + /* Enables the MCBC exception in NSS fw, 1 = enable */ + #define ATH11K_NSS_ENABLE_MCBC_EXC 1 +#define WIFILI_SCHEME_ID_INVALID -1 + diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-312-ath11k-add-ampdu-id-in-802.11-radiotap-header.patch b/package/kernel/mac80211/patches/nss/ath11k/999-312-ath11k-add-ampdu-id-in-802.11-radiotap-header.patch new file mode 100644 index 0000000000..12a035bf4e --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-312-ath11k-add-ampdu-id-in-802.11-radiotap-header.patch @@ -0,0 +1,279 @@ +From 3f962ed9a4079964c48e321fd928a2719038d881 Mon Sep 17 00:00:00 2001 +From: P Praneesh +Date: Fri, 28 May 2021 23:53:57 +0530 +Subject: [PATCH] ath11k: add ampdu id in 802.11 radiotap header + +AMPDU aggregate reference number is generated by +driver internally which is same across each +subframe of an ampdu. + +For fetching AMPDU-ID, we need to concatenate +ppdu_id from mpdu_info and tlv_usr from tlv heder. +while parsing monitor TLV data with HAL_RX_MPDU_START +TLV tag, ampdu id is fetched from mpdu_info and +updated to corresponding mac80211 structure during +ath11k_update_radiotap. + +Signed-off-by: P Praneesh +--- + drivers/net/wireless/ath/ath11k/dp_rx.c | 6 ++++++ + drivers/net/wireless/ath/ath11k/hal_rx.c | 13 ++++++++++++ + drivers/net/wireless/ath/ath11k/hal_rx.h | 16 ++++++++------ + drivers/net/wireless/ath/ath11k/hw.c | 36 +++++++++++++++++++++++++------- + drivers/net/wireless/ath/ath11k/hw.h | 1 + + 5 files changed, 58 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -5995,6 +5995,7 @@ static void ath11k_update_radiotap(struc + { + struct ieee80211_supported_band *sband; + u8 *ptr = NULL; ++ u16 ampdu_id = ppduinfo->ampdu_id[ppduinfo->userid]; + + rxs->flag |= RX_FLAG_MACTIME_START; + rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR; +@@ -6002,6 +6003,11 @@ static void ath11k_update_radiotap(struc + if (ppduinfo->nss) + rxs->nss = ppduinfo->nss; + ++ if (ampdu_id) { ++ rxs->flag |= RX_FLAG_AMPDU_DETAILS; ++ rxs->ampdu_reference = ampdu_id; ++ } ++ + if (ppduinfo->he_mu_flags) { + rxs->flag |= RX_FLAG_RADIOTAP_HE_MU; + rxs->encoding = RX_ENC_HE; +--- a/drivers/net/wireless/ath/ath11k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.c +@@ -873,6 +873,13 @@ static u16 ath11k_hal_rx_mpduinfo_get_pe + return ab->hw_params.hw_ops->mpdu_info_get_peerid(mpdu_info); + } + ++static ++u16 ath11k_hal_rxdesc_get_hal_mpdu_ppdu_id(struct ath11k_base *ab, ++ struct hal_rx_mpdu_info *mpdu_info) ++{ ++ return ab->hw_params.hw_ops->rx_desc_get_hal_ppdu_id(mpdu_info); ++} ++ + static enum hal_rx_mon_status + ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab, + struct hal_rx_mon_ppdu_info *ppdu_info, +@@ -1546,6 +1553,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc + + ppdu_info->mpdu_len += ab->hw_params.hw_ops->rx_desc_get_hal_mpdu_len(mpdu_info); + ++ if (userid < HAL_MAX_UL_MU_USERS) { ++ ppdu_info->userid = userid; ++ ppdu_info->ampdu_id[userid] = ++ ath11k_hal_rxdesc_get_hal_mpdu_ppdu_id(ab, mpdu_info); ++ } ++ + break; + } + case HAL_RXPCU_PPDU_END_INFO: { +--- a/drivers/net/wireless/ath/ath11k/hal_rx.h ++++ b/drivers/net/wireless/ath/ath11k/hal_rx.h +@@ -221,6 +221,8 @@ struct hal_rx_mon_ppdu_info { + u32 num_users; + u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP]; + struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS]; ++ u8 userid; ++ u16 ampdu_id[HAL_MAX_UL_MU_USERS]; + bool ppdu_continuation; + }; + +@@ -460,20 +462,22 @@ struct hal_rx_phyrx_rssi_legacy_info { + #define HAL_RX_MPDU_INFO_INFO0_PEERID GENMASK(31, 16) + #define HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855 GENMASK(15, 0) + #define HAL_RX_MPDU_INFO_INFO1_MPDU_LEN GENMASK(13, 0) ++#define HAL_RX_MPDU_INFO_INFO0_PPDU_ID GENMASK(31, 16) + + struct hal_rx_mpdu_info_ipq8074 { +- __le32 rsvd0; + __le32 info0; +- __le32 rsvd1[11]; + __le32 info1; ++ __le32 rsvd1[11]; ++ __le32 info2; + __le32 rsvd2[9]; + } __packed; + + struct hal_rx_mpdu_info_qcn9074 { +- __le32 rsvd0[10]; ++ __le32 rsvd0[9]; + __le32 info0; +- __le32 rsvd1[2]; + __le32 info1; ++ __le32 rsvd1[2]; ++ __le32 info2; + __le32 rsvd2[9]; + } __packed; + +@@ -493,9 +497,11 @@ struct hal_rx_mpdu_info { + + #define HAL_RX_PPDU_END_DURATION GENMASK(23, 0) + struct hal_rx_ppdu_end_duration { +- __le32 rsvd0[9]; ++ __le32 rsvd0[2]; + __le32 info0; +- __le32 rsvd1[4]; ++ __le32 rsvd1[6]; ++ __le32 info1; ++ __le32 rsvd2[4]; + } __packed; + + struct hal_rx_rxpcu_classification_overview { +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -307,6 +307,7 @@ struct ath11k_hw_ops { + void (*rx_desc_get_crypto_header)(struct hal_rx_desc *desc, + u8 *crypto_hdr, + enum hal_encrypt_type enctype); ++ u16 (*rx_desc_get_hal_ppdu_id) (struct hal_rx_mpdu_info *mpdu_info); + }; + + extern const struct ath11k_hw_ops ipq8074_ops; +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -13,6 +13,7 @@ + #include "hif.h" + #include "hal.h" + #include "hw.h" ++#include "hal_rx.h" + + /* Map from pdev index to hw mac index */ + static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx) +@@ -717,17 +718,6 @@ static u8 *ath11k_hw_qcn9074_rx_desc_get + return &desc->u.qcn9074.msdu_payload[0]; + } + +-static bool ath11k_hw_ipq9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc) +-{ +- return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) & +- RX_MPDU_START_INFO11_MAC_ADDR2_VALID; +-} +- +-static u8 *ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc) +-{ +- return desc->u.qcn9074.mpdu_start.addr2; +-} +- + static bool ath11k_hw_wcn6855_rx_desc_get_first_msdu(struct hal_rx_desc *desc) + { + return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU_WCN6855, +@@ -1085,12 +1075,27 @@ static void ath11k_hw_ipq5018_reo_setup( + } + + static u16 ++ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_ppdu_id(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PPDU_ID, ++ __le32_to_cpu(mpdu_info->u.ipq8074.info0)); ++} ++ ++static ++u16 ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_ppdu_id(struct hal_rx_mpdu_info *mpdu_info) ++{ ++ ++ return FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PPDU_ID, ++ __le32_to_cpu(mpdu_info->u.qcn9074.info0)); ++} ++ ++static u16 + ath11k_hw_ipq8074_mpdu_info_get_peerid(struct hal_rx_mpdu_info *mpdu_info) + { + u16 peer_id = 0; +- + peer_id = FIELD_GET(HAL_RX_MPDU_INFO_INFO0_PEERID, +- __le32_to_cpu(mpdu_info->u.ipq8074.info0)); ++ __le32_to_cpu(mpdu_info->u.ipq8074.info1)); + + return peer_id; + } +@@ -1196,6 +1201,7 @@ const struct ath11k_hw_ops ipq8074_ops = + .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_ppdu_id, + #ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + .rx_desc_get_offset = ath11k_hw_ipq8074_rx_desc_get_offset, + #endif +@@ -1219,6 +1225,7 @@ const struct ath11k_hw_ops ipq6018_ops = + .rx_desc_get_encrypt_type = ath11k_hw_ipq8074_rx_desc_get_encrypt_type, + .rx_desc_get_decap_type = ath11k_hw_ipq8074_rx_desc_get_decap_type, + .rx_desc_get_mesh_ctl = ath11k_hw_ipq8074_rx_desc_get_mesh_ctl, ++ .rx_desc_get_ip_valid = ath11k_hw_ipq8074_rx_desc_get_ip_valid, + .rx_desc_get_ldpc_support = ath11k_hw_ipq8074_rx_desc_get_ldpc_support, + .rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_ipq8074_rx_desc_get_mpdu_seq_ctl_vld, + .rx_desc_get_mpdu_fc_valid = ath11k_hw_ipq8074_rx_desc_get_mpdu_fc_valid, +@@ -1251,6 +1258,7 @@ const struct ath11k_hw_ops ipq6018_ops = + .rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid, + .rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr, + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_ppdu_id, + }; + + const struct ath11k_hw_ops qca6390_ops = { +@@ -1300,6 +1308,7 @@ const struct ath11k_hw_ops qca6390_ops = + .rx_desc_dot11_hdr_fields_valid = ath11k_hw_ipq8074_rx_desc_dot11_hdr_fields_valid, + .rx_desc_get_dot11_hdr = ath11k_hw_ipq8074_rx_desc_get_dot11_hdr, + .rx_desc_get_crypto_header = ath11k_hw_ipq8074_rx_desc_get_crypto_hdr, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_ppdu_id, + }; + + const struct ath11k_hw_ops qcn9074_ops = { +@@ -1341,6 +1350,7 @@ const struct ath11k_hw_ops qcn9074_ops = + .rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_ppdu_id, + #ifdef CPTCFG_ATH11K_MEM_PROFILE_512M + .rx_desc_get_offset = ath11k_hw_qcn9074_rx_desc_get_offset, + #endif +@@ -1389,6 +1399,7 @@ const struct ath11k_hw_ops wcn6855_ops = + .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_len, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_ipq8074_rx_desc_get_hal_mpdu_ppdu_id, + }; + + const struct ath11k_hw_ops wcn6750_ops = { +@@ -1405,6 +1416,7 @@ const struct ath11k_hw_ops wcn6750_ops = + .rx_desc_get_encrypt_type = ath11k_hw_qcn9074_rx_desc_get_encrypt_type, + .rx_desc_get_decap_type = ath11k_hw_qcn9074_rx_desc_get_decap_type, + .rx_desc_get_mesh_ctl = ath11k_hw_qcn9074_rx_desc_get_mesh_ctl, ++ .rx_desc_get_ip_valid = ath11k_hw_qcn9074_rx_desc_get_ip_valid, + .rx_desc_get_ldpc_support = ath11k_hw_qcn9074_rx_desc_get_ldpc_support, + .rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_qcn9074_rx_desc_get_mpdu_seq_ctl_vld, + .rx_desc_get_mpdu_fc_valid = ath11k_hw_qcn9074_rx_desc_get_mpdu_fc_valid, +@@ -1426,9 +1438,10 @@ const struct ath11k_hw_ops wcn6750_ops = + .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload, + .reo_setup = ath11k_hw_wcn6855_reo_setup, + .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, +- .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, +- .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, ++ .rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid, ++ .rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_wcn6750_get_tcl_ring_selector, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_ppdu_id, + }; + + /* IPQ5018 hw ops is similar to QCN9074 except for the dest ring remap */ +@@ -1468,10 +1481,11 @@ const struct ath11k_hw_ops ipq5018_ops = + .reo_setup = ath11k_hw_ipq5018_reo_setup, + .rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload, + .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, +- .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, +- .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, ++ .rx_desc_mac_addr2_valid = ath11k_hw_qcn9074_rx_desc_mac_addr2_valid, ++ .rx_desc_mpdu_start_addr2 = ath11k_hw_qcn9074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, + .rx_desc_get_hal_mpdu_len = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_len, ++ .rx_desc_get_hal_ppdu_id = ath11k_hw_qcn9074_rx_desc_get_hal_mpdu_ppdu_id, + }; + + #define ATH11K_TX_RING_MASK_0 BIT(0) diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-336-0001-ath11k-idr-optimization.patch b/package/kernel/mac80211/patches/nss/ath11k/999-336-0001-ath11k-idr-optimization.patch new file mode 100644 index 0000000000..ef01c639a2 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-336-0001-ath11k-idr-optimization.patch @@ -0,0 +1,132 @@ +From 58c0d08408e58f0f496127a59465726457dc72c8 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam +Date: Mon, 15 Nov 2021 17:51:43 +0530 +Subject: [PATCH] ath11k: idr optimization + +Replace idr_find and idr_remove with idr_remove. As idr_remove +itself will do idr_find. And use dma low level api. + +Signed-off-by: Tamizh Chelvam +--- + backport-include/linux/idr.h | 4 +++ + drivers/net/wireless/ath/ath11k/dp_rx.c | 52 +++++++++++---------------------- + drivers/net/wireless/ath/ath11k/dp_tx.c | 2 +- + 3 files changed, 22 insertions(+), 36 deletions(-) + +--- a/backport-include/linux/idr.h ++++ b/backport-include/linux/idr.h +@@ -8,6 +8,10 @@ + static inline void *backport_idr_remove(struct idr *idr, int id) + { + void *item = idr_find(idr, id); ++ ++ if (!item) ++ return NULL; ++ + idr_remove(idr, id); + return item; + } +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -3385,18 +3385,16 @@ try_again: + ar = ab->pdevs[mac_id].ar; + rx_ring = &ar->dp.rx_refill_buf_ring; + spin_lock_bh(&rx_ring->idr_lock); +- msdu = idr_find(&rx_ring->bufs_idr, buf_id); ++ msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); + if (unlikely(!msdu)) { + ath11k_warn(ab, "frame rx with invalid buf_id %d\n", + buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); + continue; + } + +- idr_remove(&rx_ring->bufs_idr, buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); +- + rxcb = ATH11K_SKB_RXCB(msdu); ++ + dma_unmap_single(ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); +@@ -4667,17 +4665,14 @@ ath11k_dp_process_rx_err_buf(struct ath1 + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; + + spin_lock_bh(&rx_ring->idr_lock); +- msdu = idr_find(&rx_ring->bufs_idr, buf_id); ++ msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); + if (!msdu) { + ath11k_warn(ar->ab, "rx err buf with invalid buf_id %d\n", + buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); + return -EINVAL; + } + +- idr_remove(&rx_ring->bufs_idr, buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); +- + rxcb = ATH11K_SKB_RXCB(msdu); + dma_unmap_single(ar->ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), +@@ -5083,18 +5078,16 @@ int ath11k_dp_rx_process_wbm_err(struct + rx_ring = &ar->dp.rx_refill_buf_ring; + + spin_lock_bh(&rx_ring->idr_lock); +- msdu = idr_find(&rx_ring->bufs_idr, buf_id); ++ msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); + if (!msdu) { + ath11k_warn(ab, "frame rx with invalid buf_id %d pdev %d\n", + buf_id, mac_id); +- spin_unlock_bh(&rx_ring->idr_lock); + continue; + } + +- idr_remove(&rx_ring->bufs_idr, buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); +- + rxcb = ATH11K_SKB_RXCB(msdu); ++ + dma_unmap_single(ab->dev, rxcb->paddr, + msdu->len + skb_tailroom(msdu), + DMA_FROM_DEVICE); +@@ -5209,16 +5202,14 @@ int ath11k_dp_process_rxdma_err(struct a + msdu_cookies[i]); + + spin_lock_bh(&rx_ring->idr_lock); +- skb = idr_find(&rx_ring->bufs_idr, buf_id); ++ skb = idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); + if (!skb) { + ath11k_warn(ab, "rxdma error with invalid buf_id %d\n", + buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); + continue; + } + +- idr_remove(&rx_ring->bufs_idr, buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); + + rxcb = ATH11K_SKB_RXCB(skb); + dma_unmap_single(ab->dev, rxcb->paddr, +@@ -6429,16 +6420,14 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct at + msdu_list.sw_cookie[i]); + + spin_lock_bh(&rx_ring->idr_lock); +- msdu = idr_find(&rx_ring->bufs_idr, buf_id); ++ msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ spin_unlock_bh(&rx_ring->idr_lock); + if (!msdu) { + ath11k_dbg(ar->ab, ATH11K_DBG_DATA, + "full mon msdu_pop: invalid buf_id %d\n", + buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); + break; + } +- idr_remove(&rx_ring->bufs_idr, buf_id); +- spin_unlock_bh(&rx_ring->idr_lock); + + rxcb = ATH11K_SKB_RXCB(msdu); + if (!rxcb->unmapped) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch b/package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch new file mode 100644 index 0000000000..974de14107 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-336-0002-ath11k-Use-idr_replace.patch @@ -0,0 +1,280 @@ +From 93abe1755de2727bf8fb5969bce25ae49c704484 Mon Sep 17 00:00:00 2001 +From: Tamizh Chelvam +Date: Mon, 15 Nov 2021 18:15:38 +0530 +Subject: [PATCH] ath11k: Use idr_replace + +idr_alloc has been done multiple times upon reaping the msdu +using idr_remove. This idr_alloc would take more cpu, to redue +the cpu usage call idr_replace by storing used buf_ids instead +of calling idr_alloc during replenish. + +Signed-off-by: Tamizh Chelvam +--- + drivers/net/wireless/ath/ath11k/core.h | 6 +++ + drivers/net/wireless/ath/ath11k/dp.c | 2 +- + drivers/net/wireless/ath/ath11k/dp_rx.c | 66 +++++++++++++++++++++++++-------- + drivers/net/wireless/ath/ath11k/dp_rx.h | 2 +- + 4 files changed, 59 insertions(+), 17 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/core.h ++++ b/drivers/net/wireless/ath/ath11k/core.h +@@ -662,6 +662,11 @@ struct ath11k_per_peer_tx_stats { + #define ATH11K_FLUSH_TIMEOUT (5 * HZ) + #define ATH11K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ) + ++struct ath11k_rx_buf_id { ++ struct list_head list; ++ int used_buf_id; ++}; ++ + struct ath11k { + struct ath11k_base *ab; + struct ath11k_pdev *pdev; +@@ -811,6 +816,7 @@ struct ath11k { + /* protected by conf_mutex */ + bool ps_state_enable; + bool ps_timekeeper_enable; ++ struct ath11k_rx_buf_id rx_buf_id; + }; + + struct ath11k_band_cap { +--- a/drivers/net/wireless/ath/ath11k/dp.c ++++ b/drivers/net/wireless/ath/ath11k/dp.c +@@ -897,7 +897,7 @@ int ath11k_dp_service_srng(struct ath11k + + hal_params = ab->hw_params.hal_params; + ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0, +- hal_params->rx_buf_rbm); ++ hal_params->rx_buf_rbm, NULL); + } + } + } +--- a/drivers/net/wireless/ath/ath11k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c +@@ -388,7 +388,8 @@ static inline u8 ath11k_dp_rx_h_msdu_sta + int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id, + struct dp_rxdma_ring *rx_ring, + int req_entries, +- enum hal_rx_buf_return_buf_manager mgr) ++ enum hal_rx_buf_return_buf_manager mgr, ++ u32 *buf_ids) + { + struct hal_srng *srng; + u32 *desc; +@@ -396,9 +397,15 @@ int ath11k_dp_rxbufs_replenish(struct at + int num_free; + int num_remain; + int buf_id; ++ int buf_id_index; + u32 cookie; + dma_addr_t paddr; + ++ if (!buf_ids) ++ buf_id_index = 0; ++ else ++ buf_id_index = min(req_entries, DP_RX_MAX_IDR_BUF); ++ + req_entries = min(req_entries, rx_ring->bufs_max); + + srng = &ab->hal.srng_list[rx_ring->refill_buf_ring.ring_id]; +@@ -434,8 +441,14 @@ int ath11k_dp_rxbufs_replenish(struct at + goto fail_free_skb; + + spin_lock_bh(&rx_ring->idr_lock); ++ if (buf_ids && buf_id_index) { ++ buf_id_index--; ++ buf_id = buf_ids[buf_id_index]; ++ idr_replace(&rx_ring->bufs_idr, skb, buf_id); ++ } else { + buf_id = idr_alloc(&rx_ring->bufs_idr, skb, 1, + (rx_ring->bufs_max * 3) + 1, GFP_ATOMIC); ++ } + spin_unlock_bh(&rx_ring->idr_lock); + if (buf_id <= 0) + goto fail_dma_unmap; +@@ -458,6 +471,12 @@ int ath11k_dp_rxbufs_replenish(struct at + + spin_unlock_bh(&srng->lock); + ++ while (buf_id_index--) { ++ spin_lock_bh(&rx_ring->idr_lock); ++ idr_remove(&rx_ring->bufs_idr, buf_ids[buf_id_index]); ++ spin_unlock_bh(&rx_ring->idr_lock); ++ } ++ + return req_entries - num_remain; + + fail_idr_remove: +@@ -532,7 +551,7 @@ static int ath11k_dp_rxdma_ring_buf_setu + + rx_ring->bufs_max = num_entries; + ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries, +- ar->ab->hw_params.hal_params->rx_buf_rbm); ++ ar->ab->hw_params.hal_params->rx_buf_rbm, NULL); + return 0; + } + +@@ -3347,11 +3366,14 @@ int ath11k_dp_process_rx(struct ath11k_b + struct ath11k *ar; + struct hal_reo_dest_ring *desc; + enum hal_reo_dest_ring_push_reason push_reason; ++ u32 *rx_buf_id[MAX_RADIOS]; + u32 cookie; + int i; + +- for (i = 0; i < MAX_RADIOS; i++) ++ for (i = 0; i < MAX_RADIOS; i++) { + __skb_queue_head_init(&msdu_list[i]); ++ rx_buf_id[i] = kzalloc(sizeof(u32) * DP_RX_MAX_IDR_BUF, GFP_ATOMIC); ++ } + + srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id]; + +@@ -3384,8 +3406,15 @@ try_again: + + ar = ab->pdevs[mac_id].ar; + rx_ring = &ar->dp.rx_refill_buf_ring; ++ i = num_buffs_reaped[mac_id]; ++ + spin_lock_bh(&rx_ring->idr_lock); +- msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ if (rx_buf_id[mac_id] && i < DP_RX_MAX_IDR_BUF) { ++ msdu = idr_find(&rx_ring->bufs_idr, buf_id); ++ rx_buf_id[mac_id][i] = buf_id; ++ } else { ++ msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ } + spin_unlock_bh(&rx_ring->idr_lock); + if (unlikely(!msdu)) { + ath11k_warn(ab, "frame rx with invalid buf_id %d\n", +@@ -3463,9 +3492,12 @@ try_again: + rx_ring = &ar->dp.rx_refill_buf_ring; + + ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], +- ab->hw_params.hal_params->rx_buf_rbm); ++ ab->hw_params.hal_params->rx_buf_rbm, rx_buf_id[i]); + } + exit: ++ for (i = 0; i < MAX_RADIOS; i++) ++ kfree(rx_buf_id[i]); ++ + return total_msdu_reaped; + } + +@@ -4827,7 +4859,7 @@ exit: + rx_ring = &ar->dp.rx_refill_buf_ring; + + ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i], +- ab->hw_params.hal_params->rx_buf_rbm); ++ ab->hw_params.hal_params->rx_buf_rbm, NULL); + } + + return tot_n_bufs_reaped; +@@ -5043,14 +5075,17 @@ int ath11k_dp_rx_process_wbm_err(struct + struct sk_buff *msdu; + struct sk_buff_head msdu_list[MAX_RADIOS]; + struct ath11k_skb_rxcb *rxcb; ++ u32 *wbm_err_buf_id[MAX_RADIOS]; + u32 *rx_desc; + int buf_id, mac_id; + int num_buffs_reaped[MAX_RADIOS] = {0}; + int total_num_buffs_reaped = 0; + int ret, i; + +- for (i = 0; i < ab->num_radios; i++) ++ for (i = 0; i < ab->num_radios; i++) { + __skb_queue_head_init(&msdu_list[i]); ++ wbm_err_buf_id[i] = kzalloc(sizeof(u32) * DP_RX_MAX_IDR_BUF, GFP_ATOMIC); ++ } + + srng = &ab->hal.srng_list[dp->rx_rel_ring.ring_id]; + +@@ -5076,9 +5111,15 @@ int ath11k_dp_rx_process_wbm_err(struct + + ar = ab->pdevs[mac_id].ar; + rx_ring = &ar->dp.rx_refill_buf_ring; ++ i = num_buffs_reaped[mac_id]; + + spin_lock_bh(&rx_ring->idr_lock); +- msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ if (wbm_err_buf_id[mac_id] && i < DP_RX_MAX_IDR_BUF) { ++ msdu = idr_find(&rx_ring->bufs_idr, buf_id); ++ wbm_err_buf_id[mac_id][i] = buf_id; ++ } else { ++ msdu = idr_remove(&rx_ring->bufs_idr, buf_id); ++ } + spin_unlock_bh(&rx_ring->idr_lock); + if (!msdu) { + ath11k_warn(ab, "frame rx with invalid buf_id %d pdev %d\n", +@@ -5123,7 +5164,7 @@ int ath11k_dp_rx_process_wbm_err(struct + rx_ring = &ar->dp.rx_refill_buf_ring; + + ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i], +- ab->hw_params.hal_params->rx_buf_rbm); ++ ab->hw_params.hal_params->rx_buf_rbm, wbm_err_buf_id[i]); + } + + rcu_read_lock(); +@@ -5145,6 +5186,8 @@ int ath11k_dp_rx_process_wbm_err(struct + } + rcu_read_unlock(); + done: ++ for (i = 0; i < ab->num_radios; i++) ++ kfree(wbm_err_buf_id[i]); + return total_num_buffs_reaped; + } + +@@ -5230,7 +5273,7 @@ int ath11k_dp_process_rxdma_err(struct a + + if (num_buf_freed) + ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed, +- ab->hw_params.hal_params->rx_buf_rbm); ++ ab->hw_params.hal_params->rx_buf_rbm, NULL); + + return budget - quota; + } +@@ -6182,12 +6225,12 @@ static void ath11k_dp_rx_mon_dest_proces + ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, + &dp->rxdma_mon_buf_ring, + rx_bufs_used, +- hal_params->rx_buf_rbm); ++ hal_params->rx_buf_rbm, NULL); + else + ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, + &dp->rx_refill_buf_ring, + rx_bufs_used, +- hal_params->rx_buf_rbm); ++ hal_params->rx_buf_rbm, NULL); + } + } + +@@ -6697,7 +6740,7 @@ next_entry: + ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, + &dp->rxdma_mon_buf_ring, + rx_bufs_used, +- HAL_RX_BUF_RBM_SW3_BM); ++ HAL_RX_BUF_RBM_SW3_BM, NULL); + } + + reap_status_ring: +--- a/drivers/net/wireless/ath/ath11k/dp_rx.h ++++ b/drivers/net/wireless/ath/ath11k/dp_rx.h +@@ -11,6 +11,8 @@ + + #define DP_MAX_NWIFI_HDR_LEN 36 + ++#define DP_RX_MAX_IDR_BUF 256 ++ + #define DP_RX_MPDU_ERR_FCS BIT(0) + #define DP_RX_MPDU_ERR_DECRYPT BIT(1) + #define DP_RX_MPDU_ERR_TKIP_MIC BIT(2) +@@ -125,7 +127,8 @@ int ath11k_dp_process_rx(struct ath11k_b + int ath11k_dp_rxbufs_replenish(struct ath11k_base *ab, int mac_id, + struct dp_rxdma_ring *rx_ring, + int req_entries, +- enum hal_rx_buf_return_buf_manager mgr); ++ enum hal_rx_buf_return_buf_manager mgr, ++ u32 *buf_id); + int ath11k_dp_htt_tlv_iter(struct ath11k_base *ab, const void *ptr, size_t len, + int (*iter)(struct ath11k_base *ar, u16 tag, u16 len, + const void *ptr, void *data), diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch b/package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch similarity index 78% rename from package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch rename to package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch index 1bbbdd6c74..988717c1db 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-374-ath11k-Check-skb_headroom-before-using-skb_push.patch +++ b/package/kernel/mac80211/patches/nss/ath11k/999-374-ath11k-Check-skb_headroom-before-using-skb_push.patch @@ -35,7 +35,7 @@ Signed-off-by: Tamizh Chelvam Raja --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2270,16 +2270,27 @@ static void ath11k_get_dot11_hdr_from_rx +@@ -2454,16 +2454,27 @@ static void ath11k_get_dot11_hdr_from_rx size_t hdr_len, crypto_len; struct ieee80211_hdr *hdr; u16 fc, qos_ctl = 0; @@ -63,7 +63,7 @@ Signed-off-by: Tamizh Chelvam Raja skb_push(msdu, hdr_len); hdr = (struct ieee80211_hdr *)msdu->data; hdr->frame_control = fc; -@@ -2315,6 +2326,7 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2499,6 +2510,7 @@ static void ath11k_dp_rx_h_undecap_nwifi u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; u16 qos_ctl = 0; @@ -71,7 +71,7 @@ Signed-off-by: Tamizh Chelvam Raja u8 *qos, *crypto_hdr; bool add_qos_ctrl = false; -@@ -2359,26 +2371,46 @@ static void ath11k_dp_rx_h_undecap_nwifi +@@ -2543,26 +2555,46 @@ static void ath11k_dp_rx_h_undecap_nwifi } if (!(status->flag & RX_FLAG_IV_STRIPPED)) { @@ -123,7 +123,7 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); /* original 802.11 header has a different DA and in -@@ -2487,6 +2519,7 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2671,6 +2703,7 @@ static void ath11k_dp_rx_h_undecap_eth(s u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; void *rfc1042; @@ -131,7 +131,7 @@ Signed-off-by: Tamizh Chelvam Raja struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); struct ath11k_dp_rfc1042_hdr rfc = {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}}; -@@ -2496,6 +2529,11 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2680,6 +2713,11 @@ static void ath11k_dp_rx_h_undecap_eth(s ether_addr_copy(sa, eth->h_source); rfc.snap_type = eth->h_proto; skb_pull(msdu, sizeof(struct ethhdr)); @@ -143,7 +143,7 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, sizeof(struct ath11k_dp_rfc1042_hdr)), &rfc, sizeof(struct ath11k_dp_rfc1042_hdr)); ath11k_get_dot11_hdr_from_rx_desc(ar, msdu, rxcb, status, enctype); -@@ -2513,6 +2551,11 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2697,6 +2735,11 @@ static void ath11k_dp_rx_h_undecap_eth(s skb_pull(msdu, sizeof(struct ethhdr)); /* push rfc1042/llc/snap */ @@ -155,7 +155,7 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, sizeof(struct ath11k_dp_rfc1042_hdr)), rfc1042, sizeof(struct ath11k_dp_rfc1042_hdr)); -@@ -2521,12 +2564,22 @@ static void ath11k_dp_rx_h_undecap_eth(s +@@ -2705,12 +2748,22 @@ static void ath11k_dp_rx_h_undecap_eth(s hdr_len = ieee80211_hdrlen(hdr->frame_control); if (!(status->flag & RX_FLAG_IV_STRIPPED)) { @@ -182,7 +182,51 @@ Signed-off-by: Tamizh Chelvam Raja memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); exit: -@@ -2954,10 +3007,16 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -2731,6 +2784,7 @@ static void ath11k_dp_rx_h_undecap_snap( + struct ieee80211_hdr *hdr; + size_t hdr_len; + u8 l3_pad_bytes; ++ int expand_by; + struct hal_rx_desc *rx_desc; + struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + +@@ -2755,12 +2809,22 @@ static void ath11k_dp_rx_h_undecap_snap( + hdr_len = ieee80211_hdrlen(hdr->frame_control); + + if (!(status->flag & RX_FLAG_IV_STRIPPED)) { +- memcpy(skb_push(msdu, +- ath11k_dp_rx_crypto_param_len(ar, enctype)), +- (void *)hdr + hdr_len, +- ath11k_dp_rx_crypto_param_len(ar, enctype)); ++ int crypto_param_len = ath11k_dp_rx_crypto_param_len(ar, enctype); ++ ++ if (skb_headroom(msdu) < crypto_param_len) { ++ expand_by = crypto_param_len - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } ++ memcpy(skb_push(msdu, crypto_param_len), ++ (void *)hdr + hdr_len, crypto_param_len); + } + ++ if (skb_headroom(msdu) < hdr_len) { ++ expand_by = hdr_len - skb_headroom(msdu); ++ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) ++ return; ++ } + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + } + +@@ -2889,7 +2953,7 @@ static void ath11k_dp_rx_h_mpdu(struct a + struct ieee80211_rx_status *rx_status, + bool *fast_rx) + { +- bool fill_crypto_hdr; ++ bool fill_crypto_hdr = 0; + enum hal_encrypt_type enctype; + bool is_decrypted = false; + struct ath11k_skb_rxcb *rxcb; +@@ -3122,10 +3186,16 @@ static void ath11k_dp_rx_deliver_msdu(st u8 decap = DP_RX_DECAP_TYPE_RAW; bool is_mcbc = rxcb->is_mcbc; bool is_eapol = rxcb->is_eapol; @@ -199,11 +243,11 @@ Signed-off-by: Tamizh Chelvam Raja he = skb_push(msdu, sizeof(known)); memcpy(he, &known, sizeof(known)); status->flag |= RX_FLAG_RADIOTAP_HE; -@@ -3013,6 +3072,7 @@ static void ath11k_dp_rx_deliver_msdu(st +@@ -3181,6 +3251,7 @@ static void ath11k_dp_rx_deliver_msdu(st !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED)) rx_status->flag |= RX_FLAG_8023; +exit: ieee80211_rx_napi(ar->hw, pubsta, msdu, napi); + } - if (ath11k_debugfs_is_extd_rx_stats_enabled(ar)) { diff --git a/package/kernel/mac80211/patches/nss/ath11k/999-783-001-wifi-ath11k-Fix-BCCA-counter-for-EMA.patch b/package/kernel/mac80211/patches/nss/ath11k/999-783-001-wifi-ath11k-Fix-BCCA-counter-for-EMA.patch new file mode 100644 index 0000000000..cf712593cc --- /dev/null +++ b/package/kernel/mac80211/patches/nss/ath11k/999-783-001-wifi-ath11k-Fix-BCCA-counter-for-EMA.patch @@ -0,0 +1,115 @@ +From ea4988df80e62204c411a60bafadfbff23eaa773 Mon Sep 17 00:00:00 2001 +From: Rameshkumar Sundaram +Date: Thu, 15 Jun 2023 14:33:55 +0530 +Subject: [PATCH] wifi: ath11k: Fix BCCA counter for EMA + +Currently BCCA counter is updated to FW via csa counter offs and +beacon with new countdown is updated for every beacon tx completion event. +For EMA, all EMA beacons are updated in one shot, and counter update for +every tx event will mess up the actual sequence of countdown sent over the air. + +Allow FW to update the countdown till 1 and finalize the color +change. + +Signed-off-by: Rameshkumar Sundaram +--- + drivers/net/wireless/ath/ath11k/mac.c | 21 --------------------- + drivers/net/wireless/ath/ath11k/mac.h | 1 - + drivers/net/wireless/ath/ath11k/wmi.c | 23 +++++++++++++++-------- + 3 files changed, 15 insertions(+), 30 deletions(-) + +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -1601,27 +1601,6 @@ static int ath11k_mac_setup_bcn_tmpl(str + return ath11k_mac_setup_bcn_tmpl_mbssid(arvif); + } + +-void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif) +-{ +- struct ieee80211_vif *vif = arvif->vif; +- +- if (!vif->bss_conf.color_change_active && !arvif->bcca_zero_sent) +- return; +- +- if (vif->bss_conf.color_change_active && +- ieee80211_beacon_cntdwn_is_complete(vif)) { +- arvif->bcca_zero_sent = true; +- ieee80211_color_change_finish(vif); +- return; +- } +- +- arvif->bcca_zero_sent = false; +- +- if (vif->bss_conf.color_change_active) +- ieee80211_beacon_update_cntdwn(vif); +- ath11k_mac_setup_bcn_tmpl(arvif); +-} +- + static void ath11k_control_beaconing(struct ath11k_vif *arvif, + struct ieee80211_bss_conf *info) + { +--- a/drivers/net/wireless/ath/ath11k/mac.h ++++ b/drivers/net/wireless/ath/ath11k/mac.h +@@ -170,7 +170,6 @@ enum ath11k_supported_bw ath11k_mac_mac8 + enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher); + void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb); + void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id); +-void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif); + int ath11k_mac_wait_tx_complete(struct ath11k *ar); + int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif, + enum wmi_sta_keepalive_method method, +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1874,9 +1874,10 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a + cmd->vdev_id = vdev_id; + cmd->tim_ie_offset = offs->tim_offset; + +- if (vif->bss_conf.csa_active) { ++ if (vif->bss_conf.csa_active || vif->bss_conf.color_change_active) { + cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0]; + cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1]; ++ cmd->csa_event_bitmap = cpu_to_le32(0xFFFFFFFF); + } + + cmd->buf_len = bcn->len; +@@ -7586,7 +7587,6 @@ static void ath11k_bcn_tx_status_event(s + rcu_read_unlock(); + return; + } +- ath11k_mac_bcn_tx_event(arvif); + rcu_read_unlock(); + } + +@@ -8500,10 +8500,7 @@ ath11k_wmi_process_csa_switch_count_even + { + int i; + struct ath11k_vif *arvif; +- +- /* Finish CSA once the switch count becomes NULL */ +- if (ev->current_switch_count) +- return; ++ struct ieee80211_bss_conf *bss_conf; + + rcu_read_lock(); + for (i = 0; i < ev->num_vdevs; i++) { +@@ -8515,8 +8512,18 @@ ath11k_wmi_process_csa_switch_count_even + continue; + } + +- if (arvif->is_up && arvif->vif->bss_conf.csa_active) +- ieee80211_csa_finish(arvif->vif); ++ bss_conf = &arvif->vif->bss_conf; ++ if (arvif->is_up && (bss_conf->csa_active || bss_conf->color_change_active)) { ++ if (!ev->current_switch_count) { ++ if (bss_conf->csa_active) ++ ieee80211_csa_finish(arvif->vif); ++ } else if (ev->current_switch_count > 1) { ++ ieee80211_beacon_update_cntdwn(arvif->vif); ++ } else { ++ if (bss_conf->color_change_active) ++ ieee80211_color_change_finish(arvif->vif); ++ } ++ } + } + rcu_read_unlock(); + } diff --git a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch similarity index 61% rename from package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch rename to package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch index 12feacda85..7a9b58411d 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/900-fix-build.patch +++ b/package/kernel/mac80211/patches/nss/subsys/007-fix_compilation_issue.patch @@ -1,62 +1,6 @@ ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2305,6 +2305,7 @@ static void ath11k_dp_rx_h_undecap_snap( - struct ieee80211_hdr *hdr; - size_t hdr_len; - u8 l3_pad_bytes; -+ int expand_by; - struct hal_rx_desc *rx_desc; - struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); - -@@ -2329,12 +2330,22 @@ static void ath11k_dp_rx_h_undecap_snap( - hdr_len = ieee80211_hdrlen(hdr->frame_control); - - if (!(status->flag & RX_FLAG_IV_STRIPPED)) { -- memcpy(skb_push(msdu, -- ath11k_dp_rx_crypto_param_len(ar, enctype)), -- (void *)hdr + hdr_len, -- ath11k_dp_rx_crypto_param_len(ar, enctype)); -+ int crypto_param_len = ath11k_dp_rx_crypto_param_len(ar, enctype); -+ -+ if (skb_headroom(msdu) < crypto_param_len) { -+ expand_by = crypto_param_len - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } -+ memcpy(skb_push(msdu, crypto_param_len), -+ (void *)hdr + hdr_len, crypto_param_len); - } - -+ if (skb_headroom(msdu) < hdr_len) { -+ expand_by = hdr_len - skb_headroom(msdu); -+ if (WARN_ON_ONCE(pskb_expand_head(msdu, expand_by, 0, GFP_ATOMIC))) -+ return; -+ } - memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); - } - -@@ -2464,7 +2475,7 @@ static void ath11k_dp_rx_h_mpdu(struct a - struct ieee80211_rx_status *rx_status, - bool *fast_rx) - { -- bool fill_crypto_hdr; -+ bool fill_crypto_hdr = 0; - enum hal_encrypt_type enctype; - bool is_decrypted = false; - struct ath11k_skb_rxcb *rxcb; -@@ -2479,7 +2490,8 @@ static void ath11k_dp_rx_h_mpdu(struct a - - /* PN for multicast packets will be checked in mac80211 */ - rxcb = ATH11K_SKB_RXCB(msdu); -- fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); -+ if (!ar->ab->nss.enabled) -+ fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); - rxcb->is_mcbc = fill_crypto_hdr; - - if (rxcb->is_mcbc) { --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -9228,7 +9228,7 @@ void cfg80211_bss_flush(struct wiphy *wi +@@ -9247,7 +9247,7 @@ void cfg80211_bss_flush(struct wiphy *wi * @count: the number of TBTTs until the color change happens * @color_bitmap: representations of the colors that the local BSS is aware of */ @@ -65,7 +9,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap); -@@ -9238,9 +9238,9 @@ int cfg80211_bss_color_notify(struct net +@@ -9257,9 +9257,9 @@ int cfg80211_bss_color_notify(struct net * @color_bitmap: representations of the colors that the local BSS is aware of */ static inline int cfg80211_obss_color_collision_notify(struct net_device *dev, @@ -77,7 +21,7 @@ 0, color_bitmap); } -@@ -9254,7 +9254,7 @@ static inline int cfg80211_obss_color_co +@@ -9273,7 +9273,7 @@ static inline int cfg80211_obss_color_co static inline int cfg80211_color_change_started_notify(struct net_device *dev, u8 count) { @@ -86,7 +30,7 @@ count, 0); } -@@ -9266,7 +9266,7 @@ static inline int cfg80211_color_change_ +@@ -9285,7 +9285,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_aborted_notify(struct net_device *dev) { @@ -95,7 +39,7 @@ 0, 0); } -@@ -9278,7 +9278,7 @@ static inline int cfg80211_color_change_ +@@ -9297,7 +9297,7 @@ static inline int cfg80211_color_change_ */ static inline int cfg80211_color_change_notify(struct net_device *dev) { @@ -106,7 +50,7 @@ } --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -4777,7 +4777,7 @@ void ieee80211_color_collision_detection +@@ -4779,7 +4779,7 @@ void ieee80211_color_collision_detection struct ieee80211_sub_if_data *sdata = link->sdata; sdata_lock(sdata); @@ -128,7 +72,7 @@ sdata->debugfs.subdir_stations = debugfs_create_dir("stations", --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -1407,18 +1407,6 @@ static void __sta_info_destroy_part2(str +@@ -1414,18 +1414,6 @@ static void __sta_info_destroy_part2(str WARN_ON_ONCE(ret); } @@ -149,7 +93,7 @@ --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -19414,7 +19414,7 @@ void cfg80211_ch_switch_started_notify(s +@@ -19484,7 +19484,7 @@ void cfg80211_ch_switch_started_notify(s } EXPORT_SYMBOL(cfg80211_ch_switch_started_notify); @@ -158,7 +102,7 @@ enum nl80211_commands cmd, u8 count, u64 color_bitmap) { -@@ -19428,7 +19428,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19498,7 +19498,7 @@ int cfg80211_bss_color_notify(struct net trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap); @@ -167,7 +111,7 @@ if (!msg) return -ENOMEM; -@@ -19451,7 +19451,7 @@ int cfg80211_bss_color_notify(struct net +@@ -19521,7 +19521,7 @@ int cfg80211_bss_color_notify(struct net genlmsg_end(msg, hdr); return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), diff --git a/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch b/package/kernel/mac80211/patches/nss/subsys/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch similarity index 86% rename from package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch rename to package/kernel/mac80211/patches/nss/subsys/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch index 82d8c4e05b..86b2f2169b 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch +++ b/package/kernel/mac80211/patches/nss/subsys/146-mac80211-enable-TKIP-when-using-encapsulation-offloading.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4686,8 +4686,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4689,8 +4689,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 if (!key) key = rcu_dereference(sdata->default_unicast_key); diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch similarity index 91% rename from package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch rename to package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch index a06ef7652d..ecdf4d15c0 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-001-mac80211-add-nss-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/199-001-mac80211-add-nss-support.patch @@ -53,7 +53,7 @@ Signed-off-by: Sriram R }; /** -@@ -1406,7 +1422,7 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1410,7 +1426,7 @@ ieee80211_tx_info_clear_status(struct ie * @RX_FLAG_AMPDU_EOF_BIT_KNOWN: The EOF value is known * @RX_FLAG_RADIOTAP_HE: HE radiotap data is present * (&struct ieee80211_radiotap_he, mac80211 will fill in @@ -62,7 +62,7 @@ Signed-off-by: Sriram R * - DATA3_DATA_MCS * - DATA3_DATA_DCM * - DATA3_CODING -@@ -1414,7 +1430,7 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1418,7 +1434,7 @@ ieee80211_tx_info_clear_status(struct ie * - DATA5_DATA_BW_RU_ALLOC * - DATA6_NSTS * - DATA3_STBC @@ -71,7 +71,7 @@ Signed-off-by: Sriram R * from the RX info data, so leave those zeroed when building this data) * @RX_FLAG_RADIOTAP_HE_MU: HE MU radiotap data is present * (&struct ieee80211_radiotap_he_mu) -@@ -1987,6 +2003,16 @@ static inline bool lockdep_vif_mutex_hel +@@ -1991,6 +2007,16 @@ static inline bool lockdep_vif_mutex_hel lockdep_vif_mutex_held(vif)) /** @@ -88,7 +88,7 @@ Signed-off-by: Sriram R * enum ieee80211_key_flags - key flags * * These flags are used for communication about keys between the driver -@@ -2677,6 +2703,8 @@ struct ieee80211_txq { +@@ -2682,6 +2708,8 @@ struct ieee80211_txq { * @IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX: Hardware/driver handles transmitting * multicast frames on all links, mac80211 should not do that. * @@ -97,7 +97,7 @@ Signed-off-by: Sriram R * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { -@@ -2734,6 +2762,7 @@ enum ieee80211_hw_flags { +@@ -2739,6 +2767,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP, IEEE80211_HW_DETECTS_COLOR_COLLISION, IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, @@ -105,7 +105,7 @@ Signed-off-by: Sriram R /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS -@@ -3746,6 +3775,10 @@ struct ieee80211_prep_tx_info { +@@ -3751,6 +3780,10 @@ struct ieee80211_prep_tx_info { * non-MLO connections. * The callback can sleep. * @@ -116,18 +116,18 @@ Signed-off-by: Sriram R * @prepare_multicast: Prepare for multicast filter configuration. * This callback is optional, and its return value is passed * to configure_filter(). This callback must be atomic. -@@ -4297,7 +4330,9 @@ struct ieee80211_ops { +@@ -4302,7 +4335,9 @@ struct ieee80211_ops { struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u64 changed); - + void (*nss_bss_info_changed)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, -+ u64 changed); ++ u32 changed); int (*start_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf); void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -@@ -4602,7 +4637,7 @@ struct ieee80211_ops { +@@ -4607,7 +4642,7 @@ struct ieee80211_ops { int (*reset_tid_config)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u8 tids); @@ -138,7 +138,7 @@ Signed-off-by: Sriram R struct ieee80211_sta *sta, bool enabled); --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c -@@ -496,6 +496,7 @@ static const char *hw_flag_names[] = { +@@ -505,6 +505,7 @@ static const char *hw_flag_names[] = { FLAG(SUPPORTS_CONC_MON_RX_DECAP), FLAG(DETECTS_COLOR_COLLISION), FLAG(MLO_MCAST_MULTI_LINK_TX), @@ -191,7 +191,7 @@ Signed-off-by: Sriram R u64 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) { sdata->vif.bss_conf.use_cts_prot = false; -@@ -694,12 +705,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -691,12 +702,6 @@ struct ieee80211_hw *ieee80211_alloc_hw_ NL80211_FEATURE_FULL_AP_CLIENT_STATE; wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); wiphy_ext_feature_set(wiphy, @@ -204,7 +204,7 @@ Signed-off-by: Sriram R NL80211_EXT_FEATURE_SCAN_FREQ_KHZ); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE); -@@ -1007,6 +1012,18 @@ int ieee80211_register_hw(struct ieee802 +@@ -1005,6 +1010,18 @@ int ieee80211_register_hw(struct ieee802 return -EINVAL; } @@ -225,7 +225,7 @@ Signed-off-by: Sriram R return -EINVAL; --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -2380,6 +2380,9 @@ sta_get_last_rx_stats(struct sta_info *s +@@ -2390,6 +2390,9 @@ sta_get_last_rx_stats(struct sta_info *s struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; int cpu; @@ -237,7 +237,7 @@ Signed-off-by: Sriram R --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -1028,11 +1028,23 @@ ieee80211_tx_h_stats(struct ieee80211_tx +@@ -1029,11 +1029,23 @@ ieee80211_tx_h_stats(struct ieee80211_tx { struct sk_buff *skb; int ac = -1; @@ -261,7 +261,7 @@ Signed-off-by: Sriram R ac = skb_get_queue_mapping(skb); tx->sta->deflink.tx_stats.bytes[ac] += skb->len; } -@@ -2857,7 +2869,9 @@ static struct sk_buff *ieee80211_build_h +@@ -2858,7 +2870,9 @@ static struct sk_buff *ieee80211_build_h if (unlikely(!multicast && ((skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || @@ -272,7 +272,7 @@ Signed-off-by: Sriram R info_id = ieee80211_store_ack_skb(local, skb, &info_flags, cookie); -@@ -4639,13 +4653,16 @@ static void ieee80211_8023_xmit(struct i +@@ -4642,13 +4656,16 @@ static void ieee80211_8023_xmit(struct i } if (unlikely(skb->sk && @@ -306,7 +306,7 @@ Signed-off-by: Sriram R gfp); --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2675,7 +2675,7 @@ static int ieee80211_change_bss(struct w +@@ -2678,7 +2678,7 @@ static int ieee80211_change_bss(struct w struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_link_data *link; struct ieee80211_supported_band *sband; @@ -315,7 +315,7 @@ Signed-off-by: Sriram R link = ieee80211_link_or_deflink(sdata, params->link_id, true); if (IS_ERR(link)) -@@ -2725,6 +2725,8 @@ static int ieee80211_change_bss(struct w +@@ -2728,6 +2728,8 @@ static int ieee80211_change_bss(struct w sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS; else sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS; @@ -324,7 +324,7 @@ Signed-off-by: Sriram R ieee80211_check_fast_rx_iface(sdata); } -@@ -2753,6 +2755,8 @@ static int ieee80211_change_bss(struct w +@@ -2756,6 +2758,8 @@ static int ieee80211_change_bss(struct w ieee80211_link_info_change_notify(sdata, link, changed); @@ -361,7 +361,7 @@ Signed-off-by: Sriram R { --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1845,6 +1845,8 @@ void ieee80211_vif_cfg_change_notify(str +@@ -1847,6 +1847,8 @@ void ieee80211_vif_cfg_change_notify(str void ieee80211_link_info_change_notify(struct ieee80211_sub_if_data *sdata, struct ieee80211_link_data *link, u64 changed); @@ -388,7 +388,7 @@ Signed-off-by: Sriram R + LOCAL_ENTRY + VIF_ENTRY + __field(u32, changed) -+ __field(bool, nss_ap_isolate); ++ __field(bool, nss_ap_isolate) + ), + + TP_fast_assign( diff --git a/package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch b/package/kernel/mac80211/patches/nss/subsys/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch similarity index 97% rename from package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch rename to package/kernel/mac80211/patches/nss/subsys/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch index 87c2a52b67..01740e2980 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch +++ b/package/kernel/mac80211/patches/nss/subsys/199-mac80211-fix-xmit-callback-when-hwencap-enable-in-st.patch @@ -18,7 +18,7 @@ Signed-off-by: P Praneesh --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -6213,7 +6213,13 @@ start_xmit: +@@ -6216,7 +6216,13 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); diff --git a/package/kernel/mac80211/patches/nss/subsys/203-mac80211-ath11k-fw-dynamic-muedca.patch b/package/kernel/mac80211/patches/nss/subsys/203-mac80211-ath11k-fw-dynamic-muedca.patch new file mode 100644 index 0000000000..d4410bd712 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/203-mac80211-ath11k-fw-dynamic-muedca.patch @@ -0,0 +1,203 @@ +From ed838800bb8f4c59b320395066ac356f74528a50 Mon Sep 17 00:00:00 2001 +From: Muna Sinada +Date: Wed, 29 Jul 2020 00:11:30 -0700 +Subject: [PATCH] 203-mac80211-ath11k-fw-dynamic-muedca.patch + +mac80211/ath11k:FW Initiated Dynamic MU-EDCA + +Implementing the updating of firmware initiated dynamic MU-EDCA +parameters in Beacon IE. Firmware routinely checks its clients and +updates its MU-EDCA values every 3 seconds. Firmware is tuning +MU-EDCA parameters to improve performance. As part of this process, +the firmware informs host about new MU-EDCA values utilizing +WMI_MUEDCA_PARAMS_CONFIG_EVENTID. FW expectation is that host will +update MU-EDCA parameters in the Beacon IE. +Implementation consists of: + (1) Receiving updated parameters through event in ATH11k + (2) Passing updated parameters ATH11k -> mac80211 -> cfg80211 + (3) Passing updated parameters to user space. + +Signed-off-by: Muna Sinada +--- + drivers/net/wireless/ath/ath11k/wmi.c | 97 +++++++++++++++++++++++++++++++---- + drivers/net/wireless/ath/ath11k/wmi.h | 12 +++++ + include/net/cfg80211.h | 11 ++++ + include/net/mac80211.h | 13 +++++ + include/uapi/linux/nl80211.h | 10 ++++ + net/mac80211/mlme.c | 12 +++++ + net/mac80211/trace.h | 20 ++++++++ + net/wireless/nl80211.c | 36 +++++++++++++ + 8 files changed, 200 insertions(+), 11 deletions(-) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -9327,4 +9327,15 @@ bool cfg80211_valid_disable_subchannel_b + */ + void cfg80211_links_removed(struct net_device *dev, u16 link_mask); + ++/** ++ * cfg80211_update_muedca_params_event - Notify the updated MU-EDCA parameters ++ * to user space. ++ * @wiphy: the wiphy ++ * @params: Updated MU-EDCA parameters ++ * @gfp: allocation flags ++ */ ++void cfg80211_update_muedca_params_event(struct wiphy *wiphy, ++ struct ieee80211_mu_edca_param_set ++ *params, gfp_t gfp); ++ + #endif /* __NET_CFG80211_H */ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -7363,6 +7363,20 @@ u32 ieee80211_calc_rx_airtime(struct iee + int len); + + /** ++ * ieee80211_update_muedca_params - update MU-EDCA parameters. ++ * ++ * This function is used to pass dynamically updated MU-EDCA parameters from ++ * driver to user space in order for parameters to be updated in beacon. ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @params: updated MU-EDCA paramters ++ * @gfp: allocation flags ++ */ ++void ieee80211_update_muedca_params(struct ieee80211_hw *hw, ++ struct ieee80211_mu_edca_param_set ++ *params, gfp_t gfp); ++ ++/** + * ieee80211_calc_tx_airtime - calculate estimated transmission airtime for TX. + * + * This function calculates the estimated airtime usage of a frame based on the +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -1314,6 +1314,10 @@ + * Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide + * information about the removed STA MLD setup links. + * ++ * @NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS: Updated MU-EDCA parameters from driver. ++ * This event is used to update dynamic MU-EDCA parameters in Beacon frame, ++ * coming from driver and now need to be reflected in Beacon frame. ++ * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +@@ -1569,6 +1573,7 @@ enum nl80211_commands { + + NL80211_CMD_LINKS_REMOVED, + ++ NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS, + /* add new commands above here */ + + /* used to define NL80211_CMD_MAX below */ +@@ -2815,6 +2820,8 @@ enum nl80211_commands { + * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is + * disabled. + * ++ * @NL80211_ATTR_HE_MUEDCA_PARAMS: MU-EDCA AC parameters for the ++ * %NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS command. + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -3353,6 +3360,8 @@ enum nl80211_attrs { + + NL80211_ATTR_MLO_LINK_DISABLED, + ++ NL80211_ATTR_HE_MUEDCA_PARAMS, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -7954,3 +7954,15 @@ void ieee80211_disable_rssi_reports(stru + _ieee80211_enable_rssi_reports(sdata, 0, 0); + } + EXPORT_SYMBOL(ieee80211_disable_rssi_reports); ++ ++void ieee80211_update_muedca_params(struct ieee80211_hw *hw, ++ struct ieee80211_mu_edca_param_set ++ *params, gfp_t gfp) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ ++ trace_api_update_muedca_params(local, params); ++ ++ cfg80211_update_muedca_params_event(local->hw.wiphy, params, gfp); ++} ++EXPORT_SYMBOL(ieee80211_update_muedca_params); +--- a/net/mac80211/trace.h ++++ b/net/mac80211/trace.h +@@ -3092,6 +3092,26 @@ TRACE_EVENT(stop_queue, + ) + ); + ++TRACE_EVENT(api_update_muedca_params, ++ TP_PROTO(struct ieee80211_local *local, ++ struct ieee80211_mu_edca_param_set *params), ++ ++ TP_ARGS(local, params), ++ ++ TP_STRUCT__entry( ++ LOCAL_ENTRY ++ ), ++ ++ TP_fast_assign( ++ LOCAL_ASSIGN; ++ ), ++ ++ TP_printk( ++ LOCAL_PR_FMT " updated MU-EDCA parameters", ++ LOCAL_PR_ARG ++ ) ++); ++ + #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ + + #undef TRACE_INCLUDE_PATH +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -20211,6 +20211,42 @@ nla_put_failure: + } + EXPORT_SYMBOL(cfg80211_update_owe_info_event); + ++void cfg80211_update_muedca_params_event(struct wiphy *wiphy, ++ struct ieee80211_mu_edca_param_set ++ *params, gfp_t gfp) ++{ ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ struct sk_buff *msg; ++ void *hdr; ++ ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); ++ if (!msg) ++ return; ++ ++ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS); ++ if (!hdr) ++ goto nla_put_failure; ++ ++ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) ++ goto nla_put_failure; ++ ++ if (nla_put(msg, NL80211_ATTR_HE_MUEDCA_PARAMS, ++ sizeof(struct ieee80211_mu_edca_param_set), ++ (const void *)params)) ++ goto nla_put_failure; ++ ++ genlmsg_end(msg, hdr); ++ ++ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, ++ NL80211_MCGRP_MLME, gfp); ++ return; ++ ++nla_put_failure: ++ genlmsg_cancel(msg, hdr); ++ nlmsg_free(msg); ++} ++EXPORT_SYMBOL(cfg80211_update_muedca_params_event); ++ + /* initialisation/exit functions */ + + int __init nl80211_init(void) diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch b/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch similarity index 94% rename from package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch rename to package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch index af46c8f0bf..5ae1ba64bb 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-Add-support-for-dynamic-vlan.patch +++ b/package/kernel/mac80211/patches/nss/subsys/207-ath11k-Add-support-for-dynamic-vlan.patch @@ -29,7 +29,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* misc utils */ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, -@@ -4268,6 +4271,8 @@ void __ieee80211_subif_start_xmit(struct +@@ -4271,6 +4274,8 @@ void __ieee80211_subif_start_xmit(struct struct sta_info *sta; struct sk_buff *next; int len = skb->len; @@ -38,7 +38,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { kfree_skb(skb); -@@ -4289,6 +4294,19 @@ void __ieee80211_subif_start_xmit(struct +@@ -4292,6 +4297,19 @@ void __ieee80211_subif_start_xmit(struct if (IS_ERR(sta)) sta = NULL; diff --git a/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch similarity index 95% rename from package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch rename to package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch index c9a12d5f12..38d737dc37 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/207-mac80211-add-nss-redirect-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/207-mac80211-add-nss-redirect-support.patch @@ -136,7 +136,7 @@ Signed-off-by: Sowmiya Sree Elavalagan return 0; --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -2570,6 +2570,54 @@ static bool ieee80211_frame_allowed(stru +@@ -2569,6 +2569,54 @@ static bool ieee80211_frame_allowed(stru return true; } @@ -191,7 +191,7 @@ Signed-off-by: Sowmiya Sree Elavalagan static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, struct ieee80211_rx_data *rx) { -@@ -2609,11 +2657,15 @@ static void ieee80211_deliver_skb_to_loc +@@ -2608,11 +2656,15 @@ static void ieee80211_deliver_skb_to_loc !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) ether_addr_copy(ehdr->h_dest, sdata->vif.addr); @@ -209,7 +209,7 @@ Signed-off-by: Sowmiya Sree Elavalagan --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4501,6 +4501,35 @@ static void ieee80211_mlo_multicast_tx(s +@@ -4504,6 +4504,35 @@ static void ieee80211_mlo_multicast_tx(s kfree_skb(skb); } @@ -245,7 +245,7 @@ Signed-off-by: Sowmiya Sree Elavalagan /** * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs * @skb: packet to be sent -@@ -4514,6 +4543,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -4517,6 +4546,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); const struct ethhdr *eth = (void *)skb->data; @@ -256,7 +256,7 @@ Signed-off-by: Sowmiya Sree Elavalagan if (likely(!is_multicast_ether_addr(eth->h_dest))) goto normal; -@@ -4700,6 +4733,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4703,6 +4736,9 @@ netdev_tx_t ieee80211_subif_start_xmit_8 struct ieee80211_key *key; struct sta_info *sta; diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch b/package/kernel/mac80211/patches/nss/subsys/235-001-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch similarity index 86% rename from package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch rename to package/kernel/mac80211/patches/nss/subsys/235-001-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch index 7dc88faed7..3d543d7141 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-000-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch +++ b/package/kernel/mac80211/patches/nss/subsys/235-001-mac80211-add-AP_VLAN-iftype-support-on-NSS-offload-case.patch @@ -21,7 +21,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -5102,6 +5102,17 @@ void ieee80211_sta_pspoll(struct ieee802 +@@ -5100,6 +5100,17 @@ void ieee80211_sta_pspoll(struct ieee802 */ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid); @@ -41,7 +41,7 @@ Signed-off-by: Sathishkumar Muruganandam * This is enough for the radiotap header. --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2177,7 +2177,13 @@ static int ieee80211_change_station(stru +@@ -2180,7 +2180,13 @@ static int ieee80211_change_station(stru rcu_assign_pointer(vlansdata->u.vlan.sta, sta); __ieee80211_check_fast_rx_iface(vlansdata); @@ -122,7 +122,7 @@ Signed-off-by: Sathishkumar Muruganandam netif_carrier_off(dev); --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -1759,6 +1759,12 @@ void ieee80211_sta_uapsd_trigger(struct +@@ -1656,6 +1656,12 @@ void ieee80211_sta_uapsd_trigger(struct } EXPORT_SYMBOL(ieee80211_sta_uapsd_trigger); @@ -137,8 +137,24 @@ Signed-off-by: Sathishkumar Muruganandam { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4725,7 +4725,8 @@ static void ieee80211_8023_xmit(struct i - info->flags |= info_flags; +@@ -4298,8 +4298,13 @@ void __ieee80211_subif_start_xmit(struct + sta = NULL; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { +- ap_sdata = container_of(sdata->bss, +- struct ieee80211_sub_if_data, u.ap); ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) ++ ap_sdata = container_of(sdata->bss, ++ struct ieee80211_sub_if_data, ++ u.ap); ++ else ++ ap_sdata = sdata; ++ + if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && + !is_multicast_ether_addr(skb->data)) { + if (sta) +@@ -4689,7 +4694,8 @@ static void ieee80211_8023_xmit(struct i + info->hw_queue = sdata->vif.hw_queue[queue]; - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) @@ -181,7 +197,7 @@ Signed-off-by: Sathishkumar Muruganandam drv_remove_interface(local, sdata); --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c -@@ -5235,7 +5235,8 @@ static bool ieee80211_assoc_success(stru +@@ -5259,7 +5259,8 @@ static bool ieee80211_assoc_success(stru * If we're using 4-addr mode, let the AP know that we're * doing so, so that it can create the STA VLAN on its side */ diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch b/package/kernel/mac80211/patches/nss/subsys/236-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch similarity index 78% rename from package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch rename to package/kernel/mac80211/patches/nss/subsys/236-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch index 33eb5d2001..542ab4e6a9 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch +++ b/package/kernel/mac80211/patches/nss/subsys/236-001-mac80211-add-dynamic-VLAN-support-on-NSS-offload.patch @@ -24,7 +24,7 @@ Signed-off-by: Sathishkumar Muruganandam --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -2091,6 +2091,8 @@ enum ieee80211_key_flags { +@@ -2088,6 +2088,8 @@ enum ieee80211_key_flags { * @tx_pn: PN used for TX keys, may be used by the driver as well if it * needs to do software PN assignment by itself (e.g. due to TSO) * @flags: key flags, see &enum ieee80211_key_flags. @@ -33,7 +33,7 @@ Signed-off-by: Sathishkumar Muruganandam * @keyidx: the key index (0-3) * @keylen: key material length * @key: key material. For ALG_TKIP the key is encoded as a 256-bit (32 byte) -@@ -2110,6 +2112,7 @@ struct ieee80211_key_conf { +@@ -2107,6 +2109,7 @@ struct ieee80211_key_conf { u8 hw_key_idx; s8 keyidx; u16 flags; @@ -100,3 +100,31 @@ Signed-off-by: Sathishkumar Muruganandam key->conf.link_id = -1; key->conf.cipher = cipher; +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -4650,16 +4650,25 @@ static void ieee80211_8023_xmit(struct i + struct ieee80211_key *key, struct sk_buff *skb) + { + struct ieee80211_tx_info *info; ++ struct ethhdr *ehdr = (struct ethhdr *)skb->data; + struct ieee80211_local *local = sdata->local; + struct tid_ampdu_tx *tid_tx; + struct sk_buff *seg, *next; + unsigned int skbs = 0, len = 0; + u16 queue; ++ unsigned char *ra = ehdr->h_dest; ++ bool multicast; + u8 tid; + + queue = ieee80211_select_queue(sdata, sta, skb); + skb_set_queue_mapping(skb, queue); + ++ multicast = is_multicast_ether_addr(ra); ++ ++ if (multicast && sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ !atomic_read(&sdata->u.vlan.num_mcast_sta)) ++ goto out_free; ++ + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && + test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) + goto out_free; diff --git a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch similarity index 54% rename from package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch rename to package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch index b4a735f10f..0e92c0f133 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/245-compilation_fix.patch +++ b/package/kernel/mac80211/patches/nss/subsys/245-compilation_fix.patch @@ -18,17 +18,6 @@ Signed-off-by: Gautham Kumar Senthilkumaran net/mac80211/tx.c | 54 ++++++++++++++++++++++---------- 7 files changed, 40 insertions(+), 23 deletions(-) ---- a/include/linux/backport-refcount.h -+++ b/include/linux/backport-refcount.h -@@ -247,7 +247,7 @@ static inline __must_check bool refcount - - static inline void __refcount_inc(refcount_t *r, int *oldp) - { -- __refcount_add(1, r, oldp); -+ refcount_add(1, r); - } - - /** --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -207,6 +207,7 @@ enum ieee80211_rx_flags { @@ -39,45 +28,9 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct list_head *list; struct sk_buff *skb; struct ieee80211_local *local; -@@ -292,6 +293,7 @@ struct unsol_bcast_probe_resp_data { - u8 data[]; - }; - -+ - struct ps_data { - /* yes, this looks ugly, but guarantees that we can later use - * bitmap_empty :) ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -1705,7 +1705,6 @@ static void ieee80211_iface_work(struct - - /* first process frames */ - while ((skb = skb_dequeue(&sdata->skb_queue))) { -- kcov_remote_start_common(skb_get_kcov_handle(skb)); - - if (skb->protocol == cpu_to_be16(ETH_P_TDLS)) - ieee80211_process_tdls_channel_switch(sdata, skb); -@@ -1713,17 +1712,14 @@ static void ieee80211_iface_work(struct - ieee80211_iface_process_skb(local, sdata, skb); - - kfree_skb(skb); -- kcov_remote_stop(); - } - - /* process status queue */ - while ((skb = skb_dequeue(&sdata->status_queue))) { -- kcov_remote_start_common(skb_get_kcov_handle(skb)); - - ieee80211_iface_process_status(sdata, skb); - kfree_skb(skb); - -- kcov_remote_stop(); - } - - /* then other type-dependent work */ --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4668,19 +4668,21 @@ static void ieee80211_8023_xmit(struct i +@@ -4679,19 +4679,21 @@ static void ieee80211_8023_xmit(struct i ieee80211_aggr_check(sdata, sta, skb); @@ -111,7 +64,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran } skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -@@ -4739,7 +4741,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4748,7 +4750,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ethhdr *ehdr = (struct ethhdr *)skb->data; @@ -120,7 +73,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct sta_info *sta; #ifdef CPTCFG_MAC80211_NSS_SUPPORT -@@ -4757,9 +4759,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4766,9 +4768,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto out; } @@ -137,7 +90,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4770,6 +4776,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4779,6 +4785,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); @@ -145,48 +98,18 @@ Signed-off-by: Gautham Kumar Senthilkumaran ieee80211_8023_xmit(sdata, dev, sta, key, skb); goto out; ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -5342,7 +5342,7 @@ void ieee80211_rx_list(struct ieee80211_ +@@ -6285,13 +6292,7 @@ start_xmit: + mutex_lock(&local->mtx); - if (pubsta) { - sta = container_of(pubsta, struct sta_info, sta); -- if (sta && napi) { -+ if (sta) { - if (!(status->flag & RX_FLAG_ONLY_MONITOR)) - atomic_inc(&sta->rx_drv_pkts); - } -@@ -5442,8 +5442,6 @@ void ieee80211_rx_list(struct ieee80211_ - - status->rx_flags = 0; - -- kcov_remote_start_common(skb_get_kcov_handle(skb)); + local_bh_disable(); - - /* - * Frames with failed FCS/PLCP checksum are not returned, - * all other frames are returned without radiotap header -@@ -5463,7 +5461,6 @@ void ieee80211_rx_list(struct ieee80211_ - __ieee80211_rx_handle_packet(hw, pubsta, skb, list); - } - -- kcov_remote_stop(); - return; - drop: - kfree_skb(skb); ---- a/backport-include/linux/skbuff.h -+++ b/backport-include/linux/skbuff.h -@@ -24,14 +24,6 @@ static inline void *backport___skb_push( - } - #define __skb_push LINUX_BACKPORT(__skb_push) - --static inline void *__skb_put_zero(struct sk_buff *skb, unsigned int len) --{ -- void *tmp = __skb_put(skb, len); +- /* added hardware encap check for ethernet mode */ +- if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) +- ieee80211_subif_start_xmit_8023(skb, skb->dev); +- else +- __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); - -- memset(tmp, 0, len); -- return tmp; --} -- - static inline void *skb_put_zero(struct sk_buff *skb, unsigned int len) - { - void *tmp = skb_put(skb, len); ++ __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); + local_bh_enable(); + + mutex_unlock(&local->mtx); diff --git a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch similarity index 95% rename from package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch rename to package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch index d3e6b9850b..e1b46836c6 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/300-mac80211-nss-mesh-offload-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/300-ath11k-nss-mesh-offload-support.patch @@ -66,19 +66,19 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /* -@@ -794,6 +803,11 @@ struct ieee80211_bss_conf { - bool eht_mu_beamformer; - bool nss_ap_isolate; - enum nl80211_beacon_tx_mode beacon_tx_mode; +@@ -790,6 +799,11 @@ struct ieee80211_bss_conf { + bool he_full_ul_mumimo; + bool eht_su_beamformer; + bool eht_su_beamformee; + + /* Mesh configuration for nss offload */ + u8 nss_offld_ttl; + bool nss_offld_mesh_forward_enabled; + u32 nss_offld_mpath_refresh_time; + bool eht_mu_beamformer; + bool nss_ap_isolate; }; - - /** -@@ -1273,6 +1287,8 @@ struct ieee80211_rate_status { +@@ -1275,6 +1289,8 @@ struct ieee80211_rate_status { * @ack_hwtstamp: Hardware timestamp of the received ack in nanoseconds * Only needed for Timing measurement and Fine timing measurement action * frames. Only reported by devices that have timestamping enabled. @@ -87,7 +87,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran */ struct ieee80211_tx_status { struct ieee80211_sta *sta; -@@ -1283,6 +1299,8 @@ struct ieee80211_tx_status { +@@ -1285,6 +1301,8 @@ struct ieee80211_tx_status { u8 n_rates; struct list_head *free_list; @@ -96,7 +96,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; /** -@@ -1775,6 +1793,7 @@ struct ieee80211_channel_switch { +@@ -1777,6 +1795,7 @@ struct ieee80211_channel_switch { * this is not pure P2P vif. * @IEEE80211_VIF_DISABLE_SMPS_OVERRIDE: disable user configuration of * SMPS mode via debugfs. @@ -104,7 +104,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran */ enum ieee80211_vif_flags { IEEE80211_VIF_BEACON_FILTER = BIT(0), -@@ -1782,6 +1801,7 @@ enum ieee80211_vif_flags { +@@ -1784,6 +1803,7 @@ enum ieee80211_vif_flags { IEEE80211_VIF_SUPPORTS_UAPSD = BIT(2), IEEE80211_VIF_GET_NOA_UPDATE = BIT(3), IEEE80211_VIF_DISABLE_SMPS_OVERRIDE = BIT(4), @@ -112,7 +112,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran }; -@@ -2765,6 +2785,7 @@ enum ieee80211_hw_flags { +@@ -2771,6 +2791,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_DETECTS_COLOR_COLLISION, IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, @@ -120,7 +120,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS -@@ -4265,6 +4286,8 @@ struct ieee80211_prep_tx_info { +@@ -4271,6 +4292,8 @@ struct ieee80211_prep_tx_info { * @set_sar_specs: Update the SAR (TX power) settings. * @sta_set_decap_offload: Called to notify the driver when a station is allowed * to use rx decapsulation offload @@ -129,7 +129,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran * @add_twt_setup: Update hw with TWT agreement parameters received from the peer. * This callback allows the hw to check if requested parameters * are supported and if there is enough room for a new agreement. -@@ -4648,6 +4671,12 @@ struct ieee80211_ops { +@@ -4654,6 +4677,12 @@ struct ieee80211_ops { void (*sta_set_decap_offload)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enabled); @@ -142,7 +142,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran void (*add_twt_setup)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, struct ieee80211_twt_setup *twt); -@@ -7481,4 +7510,100 @@ int ieee80211_set_active_links(struct ie +@@ -7512,4 +7541,100 @@ int ieee80211_set_active_links(struct ie void ieee80211_set_active_links_async(struct ieee80211_vif *vif, u16 active_links); @@ -245,7 +245,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran #endif /* MAC80211_H */ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2514,6 +2514,7 @@ static int ieee80211_update_mesh_config( +@@ -2522,6 +2522,7 @@ static int ieee80211_update_mesh_config( struct mesh_config *conf; struct ieee80211_sub_if_data *sdata; struct ieee80211_if_mesh *ifmsh; @@ -253,7 +253,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran sdata = IEEE80211_DEV_TO_SUB_IF(dev); ifmsh = &sdata->u.mesh; -@@ -2530,8 +2531,11 @@ static int ieee80211_update_mesh_config( +@@ -2538,8 +2539,11 @@ static int ieee80211_update_mesh_config( conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks; if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask)) conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries; @@ -266,7 +266,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) conf->element_ttl = nconf->element_ttl; if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) { -@@ -2545,8 +2549,12 @@ static int ieee80211_update_mesh_config( +@@ -2553,8 +2557,12 @@ static int ieee80211_update_mesh_config( if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask)) conf->dot11MeshHWMPmaxPREQretries = nconf->dot11MeshHWMPmaxPREQretries; @@ -280,7 +280,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask)) conf->min_discovery_timeout = nconf->min_discovery_timeout; if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask)) -@@ -2581,8 +2589,12 @@ static int ieee80211_update_mesh_config( +@@ -2589,8 +2597,12 @@ static int ieee80211_update_mesh_config( if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) conf->dot11MeshHWMPRannInterval = nconf->dot11MeshHWMPRannInterval; @@ -294,7 +294,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { /* our RSSI threshold implementation is supported only for * devices that report signal in dBm. -@@ -2624,6 +2636,7 @@ static int ieee80211_update_mesh_config( +@@ -2632,6 +2644,7 @@ static int ieee80211_update_mesh_config( conf->dot11MeshConnectedToAuthServer = nconf->dot11MeshConnectedToAuthServer; ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); @@ -330,7 +330,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran sdata, fmt, ##__VA_ARGS__) --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c -@@ -497,6 +497,7 @@ static const char *hw_flag_names[] = { +@@ -506,6 +506,7 @@ static const char *hw_flag_names[] = { FLAG(DETECTS_COLOR_COLLISION), FLAG(MLO_MCAST_MULTI_LINK_TX), FLAG(SUPPORTS_NSS_OFFLOAD), @@ -340,7 +340,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c -@@ -569,3 +569,23 @@ int drv_change_sta_links(struct ieee8021 +@@ -579,3 +579,23 @@ int drv_change_sta_links(struct ieee8021 return 0; } @@ -366,7 +366,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran +#endif --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h -@@ -1567,4 +1567,10 @@ int drv_change_sta_links(struct ieee8021 +@@ -1571,4 +1571,10 @@ int drv_change_sta_links(struct ieee8021 struct ieee80211_sta *sta, u16 old_links, u16 new_links); @@ -379,7 +379,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran #endif /* __MAC80211_DRIVER_OPS */ --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h -@@ -316,6 +316,10 @@ void mesh_rx_path_sel_frame(struct ieee8 +@@ -320,6 +320,10 @@ void mesh_rx_path_sel_frame(struct ieee8 struct ieee80211_mgmt *mgmt, size_t len); struct mesh_path * mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); @@ -390,7 +390,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran int mesh_path_add_gate(struct mesh_path *mpath); int mesh_path_send_to_gates(struct mesh_path *mpath); -@@ -357,6 +361,7 @@ void mesh_path_discard_frame(struct ieee +@@ -361,6 +365,7 @@ void mesh_path_discard_frame(struct ieee void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); @@ -1173,7 +1173,16 @@ Signed-off-by: Gautham Kumar Senthilkumaran void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -2633,6 +2633,9 @@ static struct sk_buff *ieee80211_build_h +@@ -2610,7 +2610,7 @@ static struct sk_buff *ieee80211_build_h + bool multicast; + u16 info_id = 0; + struct ieee80211_chanctx_conf *chanctx_conf = NULL; +- enum nl80211_band band; ++ enum nl80211_band band = 0; + int ret; + u8 link_id = u32_get_bits(ctrl_flags, IEEE80211_TX_CTRL_MLO_LINK); + +@@ -2622,6 +2622,9 @@ static struct sk_buff *ieee80211_build_h info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; #endif @@ -1183,7 +1192,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran /* convert Ethernet header to proper 802.11 header (based on * operation mode) */ ethertype = (skb->data[12] << 8) | skb->data[13]; -@@ -2703,6 +2706,13 @@ static struct sk_buff *ieee80211_build_h +@@ -2692,6 +2695,13 @@ static struct sk_buff *ieee80211_build_h break; #ifdef CPTCFG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: @@ -1197,7 +1206,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran if (!is_multicast_ether_addr(skb->data)) { struct sta_info *next_hop; bool mpp_lookup = true; -@@ -2966,10 +2976,10 @@ static struct sk_buff *ieee80211_build_h +@@ -2955,10 +2965,10 @@ static struct sk_buff *ieee80211_build_h skb_reset_mac_header(skb); @@ -1212,7 +1221,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran info->ack_frame_id = info_id; info->band = band; -@@ -4284,6 +4294,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4275,6 +4285,7 @@ void __ieee80211_subif_start_xmit(struct struct sk_buff *next; int len = skb->len; struct ieee80211_key *key = NULL; @@ -1220,11 +1229,11 @@ Signed-off-by: Gautham Kumar Senthilkumaran struct ieee80211_sub_if_data *ap_sdata; if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) { -@@ -4359,9 +4370,15 @@ void __ieee80211_subif_start_xmit(struct +@@ -4351,9 +4362,15 @@ void __ieee80211_subif_start_xmit(struct goto out; } -- ieee80211_tx_stats(dev, skb->len); +- dev_sw_netstats_tx_add(dev, 1, skb->len); - - ieee80211_xmit(sdata, sta, skb); + info = IEEE80211_SKB_CB(skb); @@ -1233,7 +1242,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran + key = rcu_dereference(sta->ptk[sta->ptk_idx]); + ieee80211_8023_xmit(sdata, dev, sta, key, skb); + } else { -+ ieee80211_tx_stats(dev, skb->len); ++ dev_sw_netstats_tx_add(dev, 1, skb->len); + ieee80211_xmit(sdata, sta, skb); + } } diff --git a/package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch b/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch similarity index 90% rename from package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch rename to package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch index 6a37ba0e1a..0704e8fcf7 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/335-0003-mac80211-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch +++ b/package/kernel/mac80211/patches/nss/subsys/335-0003-ath11k-skip-HAL_TCL_DATA_CMD_INFO2_TID_OVERWRITE-con.patch @@ -16,7 +16,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -2727,6 +2727,8 @@ struct ieee80211_txq { +@@ -2733,6 +2733,8 @@ struct ieee80211_txq { * * @IEEE80211_HW_SUPPORTS_NSS_OFFLOAD: Hardware/driver supports NSS offload * @@ -25,7 +25,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { -@@ -2786,6 +2788,7 @@ enum ieee80211_hw_flags { +@@ -2792,6 +2794,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_MLO_MCAST_MULTI_LINK_TX, IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, @@ -35,7 +35,7 @@ Signed-off-by: Gautham Kumar Senthilkumaran NUM_IEEE80211_HW_FLAGS --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c -@@ -498,6 +498,7 @@ static const char *hw_flag_names[] = { +@@ -507,6 +507,7 @@ static const char *hw_flag_names[] = { FLAG(MLO_MCAST_MULTI_LINK_TX), FLAG(SUPPORTS_NSS_OFFLOAD), FLAG(SUPPORTS_MESH_NSS_OFFLOAD), diff --git a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch b/package/kernel/mac80211/patches/nss/subsys/335-0005-mac80211-simple-tx-for-AP-mode.patch similarity index 93% rename from package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch rename to package/kernel/mac80211/patches/nss/subsys/335-0005-mac80211-simple-tx-for-AP-mode.patch index d859d03800..314bcbe549 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/335-0005-mac80211-simple-tx-for-AP-mode.patch +++ b/package/kernel/mac80211/patches/nss/subsys/335-0005-mac80211-simple-tx-for-AP-mode.patch @@ -14,7 +14,7 @@ Signed-off-by: Aloka Dixit --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4748,6 +4748,70 @@ out_free: +@@ -4762,6 +4762,67 @@ out_free: kfree_skb(skb); } @@ -58,7 +58,6 @@ Signed-off-by: Aloka Dixit + if (sta) { + sta->deflink.tx_stats.bytes[q_map] += skb->len; + sta->deflink.tx_stats.packets[q_map]++; -+ atomic_inc(&sta->tx_netif_pkts); + } + + spin_lock_irqsave(&local->queue_stop_reason_lock, flags); @@ -78,14 +77,12 @@ Signed-off-by: Aloka Dixit + + drv_tx(local, &control, skb); + -+ if (sta) -+ atomic_inc(&sta->tx_drv_pkts); +} + netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev) { -@@ -4787,6 +4851,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4801,6 +4862,11 @@ netdev_tx_t ieee80211_subif_start_xmit_8 if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))) goto skip_offload; diff --git a/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch b/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch similarity index 93% rename from package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch rename to package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch index d29a05f139..0b89a11957 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/336-mac80211-Mesh-Fast-rx-support.patch +++ b/package/kernel/mac80211/patches/nss/subsys/336-mac80211-Mesh-Fast-rx-support.patch @@ -20,7 +20,7 @@ Signed-off-by: Sriram R --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1747,6 +1747,8 @@ static void sta_apply_mesh_params(struct +@@ -1750,6 +1750,8 @@ static void sta_apply_mesh_params(struct /* init at low value */ ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, 10); @@ -29,7 +29,7 @@ Signed-off-by: Sriram R break; case NL80211_PLINK_LISTEN: case NL80211_PLINK_BLOCKED: -@@ -1761,6 +1763,7 @@ static void sta_apply_mesh_params(struct +@@ -1764,6 +1766,7 @@ static void sta_apply_mesh_params(struct ieee80211_mps_sta_status_update(sta); changed |= ieee80211_mps_set_sta_local_pm(sta, NL80211_MESH_POWER_UNKNOWN); @@ -94,7 +94,7 @@ Signed-off-by: Sriram R if (action) { --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -4663,10 +4663,15 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4649,10 +4649,15 @@ void ieee80211_check_fast_rx(struct sta_ break; case NL80211_IFTYPE_MESH_POINT: @@ -112,7 +112,7 @@ Signed-off-by: Sriram R break; default: goto clear; -@@ -4707,7 +4712,7 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4693,7 +4698,7 @@ void ieee80211_check_fast_rx(struct sta_ __release(check_fast_rx); if (assign) @@ -121,7 +121,7 @@ Signed-off-by: Sriram R offload_flags = get_bss_sdata(sdata)->vif.offload_flags; offload = offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED; -@@ -4890,6 +4895,10 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4875,6 +4880,10 @@ static bool ieee80211_invoke_fast_rx(str u8 sa[ETH_ALEN]; } addrs __aligned(2); struct ieee80211_sta_rx_stats *stats; @@ -132,7 +132,7 @@ Signed-off-by: Sriram R /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write * to a common data structure; drivers can implement that per queue -@@ -4939,6 +4948,37 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4924,6 +4933,37 @@ static bool ieee80211_invoke_fast_rx(str snap_offs += IEEE80211_CCMP_HDR_LEN; } @@ -170,7 +170,7 @@ Signed-off-by: Sriram R if (!ieee80211_vif_is_mesh(&rx->sdata->vif) && !(status->rx_flags & IEEE80211_RX_AMSDU)) { if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) -@@ -4976,9 +5016,33 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4961,9 +5001,33 @@ static bool ieee80211_invoke_fast_rx(str return true; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch similarity index 79% rename from package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch rename to package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch index e4890a3654..c8d719006d 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/342-mac80211-fix-unconditional-sta-usage.patch +++ b/package/kernel/mac80211/patches/nss/subsys/342-mac80211-fix-unconditional-sta-usage.patch @@ -33,16 +33,19 @@ Signed-off-by: Tamizh Chelvam --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4725,12 +4725,12 @@ static void ieee80211_8023_xmit(struct i +@@ -4696,7 +4696,7 @@ static void ieee80211_8023_xmit(struct i - if (unlikely(skb->sk && - skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && -- !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) -+ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta)) - info->ack_frame_id = ieee80211_store_ack_skb(local, skb, + ieee80211_aggr_check(sdata, sta, skb); + +- if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { ++ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); + if (tid_tx) { +@@ -4747,7 +4747,7 @@ static void ieee80211_8023_xmit(struct i &info->flags, NULL); - ieee80211_tx_stats(dev, len); + dev_sw_netstats_tx_add(dev, skbs, len); - if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) { + if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { sta->deflink.tx_stats.packets[queue] += skbs; diff --git a/package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch b/package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch new file mode 100644 index 0000000000..808f69e644 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/345-mac80211-fix-mixed-declaration.patch @@ -0,0 +1,52 @@ +From b3215eee07d071137e6977d60eee3cf685241fbb Mon Sep 17 00:00:00 2001 +From: Hari Chandrakanthan +Date: Thu, 3 Feb 2022 13:55:53 +0530 +Subject: [PATCH] mac80211 : fix mixed declaration + +Fix mixed declaration in the api ieee80211_parse_ch_switch_ie + +Signed-off-by: Hari Chandrakanthan +--- + net/mac80211/spectmgmt.c | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -33,7 +33,10 @@ int ieee80211_parse_ch_switch_ie(struct + struct cfg80211_chan_def new_vht_chandef = {}; + const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; + const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; ++ struct ieee80211_vht_operation vht_oper; ++ struct ieee80211_ht_operation ht_oper; + int secondary_channel_offset = -1; ++ u8 new_seg1; + + memset(csa_ie, 0, sizeof(*csa_ie)); + +@@ -133,20 +136,13 @@ int ieee80211_parse_ch_switch_ie(struct + } + + if (wide_bw_chansw_ie) { +- u8 new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1; +- struct ieee80211_vht_operation vht_oper = { +- .chan_width = +- wide_bw_chansw_ie->new_channel_width, +- .center_freq_seg0_idx = +- wide_bw_chansw_ie->new_center_freq_seg0, +- .center_freq_seg1_idx = new_seg1, ++ new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1; ++ vht_oper.chan_width = wide_bw_chansw_ie->new_channel_width; ++ vht_oper.center_freq_seg0_idx = wide_bw_chansw_ie->new_center_freq_seg0; ++ vht_oper.center_freq_seg1_idx = new_seg1; + /* .basic_mcs_set doesn't matter */ +- }; +- struct ieee80211_ht_operation ht_oper = { +- .operation_mode = +- cpu_to_le16(new_seg1 << +- IEEE80211_HT_OP_MODE_CCFS2_SHIFT), +- }; ++ ht_oper.operation_mode = cpu_to_le16(new_seg1 << ++ IEEE80211_HT_OP_MODE_CCFS2_SHIFT); + + /* default, for the case of IEEE80211_VHT_CHANWIDTH_USE_HT, + * to the previously parsed chandef diff --git a/package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch b/package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch new file mode 100644 index 0000000000..df2b3a9257 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/346-mac80211-fix-bw-change-to-40Mhz-during-channel-switc.patch @@ -0,0 +1,34 @@ +From 9c7571646a01eedb85350dfce12b499a0267ab2b Mon Sep 17 00:00:00 2001 +From: Hari Chandrakanthan +Date: Thu, 3 Feb 2022 14:01:57 +0530 +Subject: [PATCH] mac80211 : fix bw change to 40Mhz during channel switch + +When AP reduces its channel bandwidth to 40Mhz, the associated +sta reduces the channel bandwidth to 20Mhz. + +From spec 802.11 ac, section 8.4.2.165 : +The Wide Bandwidth Channel Switch subelement is present under the following conditions: +1.Channel switching to a BSS operating channel width of 40 MHz or wider +2.Extended channel switching to a BSS operating channel width of 80 MHz or wider + +So when wide bandwidth channel switch subelement is present, +the default bandwidth is chosen as 40Mhz. + +Signed-off-by: Hari Chandrakanthan +--- + net/mac80211/spectmgmt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -136,6 +136,10 @@ int ieee80211_parse_ch_switch_ie(struct + } + + if (wide_bw_chansw_ie) { ++ csa_ie->chandef.width = NL80211_CHAN_WIDTH_40; ++ csa_ie->chandef.center_freq1 = ++ ieee80211_channel_to_frequency(wide_bw_chansw_ie->new_center_freq_seg0, ++ new_chan->band); + new_seg1 = wide_bw_chansw_ie->new_center_freq_seg1; + vht_oper.chan_width = wide_bw_chansw_ie->new_channel_width; + vht_oper.center_freq_seg0_idx = wide_bw_chansw_ie->new_center_freq_seg0; diff --git a/package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch b/package/kernel/mac80211/patches/nss/subsys/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch similarity index 95% rename from package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch rename to package/kernel/mac80211/patches/nss/subsys/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch index d128824140..ba80b62d0a 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch +++ b/package/kernel/mac80211/patches/nss/subsys/353-mac80211-fix-dynamic-vlan-warning-with-monitor-interface-restart.patch @@ -21,7 +21,7 @@ Signed-off-by: Nagarajan Maran --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -994,7 +994,8 @@ static bool ieee80211_set_sdata_offload_ +@@ -998,7 +998,8 @@ static bool ieee80211_set_sdata_offload_ flags |= IEEE80211_OFFLOAD_DECAP_ENABLED; if (local->monitors && diff --git a/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch b/package/kernel/mac80211/patches/nss/subsys/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch similarity index 94% rename from package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch rename to package/kernel/mac80211/patches/nss/subsys/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch index 14fd82cbea..55380f59d3 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch +++ b/package/kernel/mac80211/patches/nss/subsys/640-006-01-mac80211-Remove-unused-RX_FLAGS-from-mac80211_rx_fla.patch @@ -14,7 +14,7 @@ Signed-off-by: P Praneesh --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1387,8 +1387,6 @@ ieee80211_tx_info_clear_status(struct ie +@@ -1407,8 +1407,6 @@ ieee80211_tx_info_clear_status(struct ie * @RX_FLAG_AMPDU_IS_LAST: this subframe is the last subframe of the A-MPDU * @RX_FLAG_AMPDU_DELIM_CRC_ERROR: A delimiter CRC error has been detected * on this subframe @@ -23,7 +23,7 @@ Signed-off-by: P Praneesh * @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was * done by the hardware * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without -@@ -1460,22 +1458,21 @@ enum mac80211_rx_flags { +@@ -1480,22 +1478,21 @@ enum mac80211_rx_flags { RX_FLAG_AMPDU_LAST_KNOWN = BIT(12), RX_FLAG_AMPDU_IS_LAST = BIT(13), RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(14), @@ -63,7 +63,7 @@ Signed-off-by: P Praneesh /** --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -527,18 +527,13 @@ ieee80211_add_rx_radiotap_header(struct +@@ -507,18 +507,13 @@ ieee80211_add_rx_radiotap_header(struct flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST; if (status->flag & RX_FLAG_AMPDU_DELIM_CRC_ERROR) flags |= IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR; diff --git a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch b/package/kernel/mac80211/patches/nss/subsys/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch similarity index 70% rename from package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch rename to package/kernel/mac80211/patches/nss/subsys/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch index 70e2603c8c..13977ab665 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch +++ b/package/kernel/mac80211/patches/nss/subsys/657-mac80211-Avoid-encapsulation-of-EAPOL-frames-if-OFFL.patch @@ -20,7 +20,7 @@ Signed-off-by: Aaradhana Sahu --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -2062,6 +2062,11 @@ netdev_tx_t ieee80211_subif_start_xmit(s +@@ -2063,6 +2063,11 @@ netdev_tx_t ieee80211_subif_start_xmit(s struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, struct net_device *dev); @@ -41,23 +41,10 @@ Signed-off-by: Aaradhana Sahu - struct ieee80211_key *key, struct sk_buff *skb); + struct ieee80211_key *key, struct sk_buff *skb, + u32 info_flags, u32 ctrl_flags, u64 *cookie); + /* misc utils */ - static inline void ieee80211_tx_stats(struct net_device *dev, u32 len) - { -@@ -4310,13 +4311,18 @@ void __ieee80211_subif_start_xmit(struct - atomic_inc(&sta->tx_netif_pkts); - - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { -- ap_sdata = container_of(sdata->bss, -- struct ieee80211_sub_if_data, u.ap); -+ if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD)) -+ ap_sdata = container_of(sdata->bss, -+ struct ieee80211_sub_if_data, -+ u.ap); -+ else -+ ap_sdata = sdata; -+ - if (ap_sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED && + static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, +@@ -4320,7 +4321,7 @@ void __ieee80211_subif_start_xmit(struct !is_multicast_ether_addr(skb->data)) { if (sta) key = rcu_dereference(sta->ptk[sta->ptk_idx]); @@ -66,16 +53,16 @@ Signed-off-by: Aaradhana Sahu rcu_read_unlock(); return; } -@@ -4374,7 +4378,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4366,7 +4367,7 @@ void __ieee80211_subif_start_xmit(struct if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { if (sta) key = rcu_dereference(sta->ptk[sta->ptk_idx]); - ieee80211_8023_xmit(sdata, dev, sta, key, skb); + ieee80211_8023_xmit(sdata, dev, sta, key, skb, info_flags, ctrl_flags, cookie); } else { - ieee80211_tx_stats(dev, skb->len); + dev_sw_netstats_tx_add(dev, 1, skb->len); ieee80211_xmit(sdata, sta, skb); -@@ -4657,19 +4663,29 @@ static bool ieee80211_tx_8023(struct iee +@@ -4664,7 +4665,8 @@ static bool ieee80211_tx_8023(struct iee static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -84,51 +71,32 @@ Signed-off-by: Aaradhana Sahu + u32 info_flags, u32 ctrl_flags, u64 *cookie) { struct ieee80211_tx_info *info; -+ struct ethhdr *ehdr = (struct ethhdr *)skb->data; - struct ieee80211_local *local = sdata->local; - struct tid_ampdu_tx *tid_tx; - struct sk_buff *seg, *next; - unsigned int skbs = 0, len = 0; - u16 queue; -+ unsigned char *ra = ehdr->h_dest; -+ bool multicast; - u8 tid; - - queue = ieee80211_select_queue(sdata, sta, skb); - skb_set_queue_mapping(skb, queue); - -+ multicast = is_multicast_ether_addr(ra); -+ -+ if (multicast && sdata->vif.type == NL80211_IFTYPE_AP_VLAN && -+ !atomic_read(&sdata->u.vlan.num_mcast_sta)) -+ goto out_free; -+ - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && - test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) - goto out_free; -@@ -4704,6 +4720,7 @@ static void ieee80211_8023_xmit(struct i + struct ethhdr *ehdr = (struct ethhdr *)skb->data; +@@ -4720,6 +4722,7 @@ static void ieee80211_8023_xmit(struct i info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); + info->flags |= info_flags; info->hw_queue = sdata->vif.hw_queue[queue]; - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4723,9 +4740,10 @@ static void ieee80211_8023_xmit(struct i + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && +@@ -4740,11 +4743,12 @@ static void ieee80211_8023_xmit(struct i memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); } - if (unlikely(skb->sk && - skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS && -- !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta)) + if (unlikely(((skb->sk && + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || + ((ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && !multicast)) && -+ !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) + !ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD))) info->ack_frame_id = ieee80211_store_ack_skb(local, skb, - &info->flags, NULL); +- &info->flags, NULL); ++ &info->flags, cookie); -@@ -4750,7 +4768,8 @@ out_free: + dev_sw_netstats_tx_add(dev, skbs, len); + if (!ieee80211_hw_check(&local->hw, SUPPORTS_NSS_OFFLOAD) && sta) { +@@ -4764,7 +4768,8 @@ out_free: void ieee80211_8023_xmit_ap(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, @@ -138,7 +106,7 @@ Signed-off-by: Aaradhana Sahu { struct ieee80211_tx_info *info; struct ieee80211_local *local = sdata->local; -@@ -4759,6 +4778,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4773,6 +4778,9 @@ void ieee80211_8023_xmit_ap(struct ieee8 unsigned long flags; int q; u16 q_map; @@ -148,7 +116,7 @@ Signed-off-by: Aaradhana Sahu /* * If the skb is shared we need to obtain our own copy. -@@ -4770,11 +4792,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 +@@ -4784,11 +4792,13 @@ void ieee80211_8023_xmit_ap(struct ieee8 info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); @@ -165,9 +133,9 @@ Signed-off-by: Aaradhana Sahu info->flags |= IEEE80211_TX_CTL_HW_80211_ENCAP; info->control.vif = &sdata->vif; -@@ -4811,14 +4835,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 - if (sta) - atomic_inc(&sta->tx_drv_pkts); +@@ -4822,14 +4832,23 @@ void ieee80211_8023_xmit_ap(struct ieee8 + drv_tx(local, &control, skb); + } - netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, @@ -190,7 +158,7 @@ Signed-off-by: Aaradhana Sahu #ifdef CPTCFG_MAC80211_NSS_SUPPORT ieee80211_xmit_nss_fixup(skb, dev); -@@ -4834,14 +4867,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4845,14 +4864,15 @@ netdev_tx_t ieee80211_subif_start_xmit_8 kfree_skb(skb); goto out; } @@ -208,7 +176,7 @@ Signed-off-by: Aaradhana Sahu goto skip_offload; key = rcu_dereference(sta->ptk[sta->ptk_idx]); -@@ -4852,13 +4886,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 +@@ -4863,13 +4883,13 @@ netdev_tx_t ieee80211_subif_start_xmit_8 goto skip_offload; if (sdata->vif.type == NL80211_IFTYPE_AP) { @@ -224,18 +192,15 @@ Signed-off-by: Aaradhana Sahu goto out; skip_offload: -@@ -6364,13 +6398,10 @@ start_xmit: +@@ -6375,7 +6395,10 @@ start_xmit: mutex_lock(&local->mtx); local_bh_disable(); -- -- /* added hardware encap check for ethernet mode */ - if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) -- ieee80211_subif_start_xmit_8023(skb, skb->dev); +- __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); ++ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) + __ieee80211_subif_start_xmit_8023(skb, skb->dev, flags, ctrl_flags, cookie); - else - __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); -- ++ else ++ __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags, cookie); local_bh_enable(); mutex_unlock(&local->mtx); diff --git a/package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch b/package/kernel/mac80211/patches/nss/subsys/686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch similarity index 88% rename from package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch rename to package/kernel/mac80211/patches/nss/subsys/686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch index 6614d8d496..62916f15ed 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/913-686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch +++ b/package/kernel/mac80211/patches/nss/subsys/686-mac80211-fix-RCU-stall-in-mesh-fast-xmit-path.patch @@ -72,7 +72,7 @@ Signed-off-by: P Praneesh --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2347,7 +2347,7 @@ static void mpath_set_pinfo(struct mesh_ +@@ -2349,7 +2349,7 @@ static void mpath_set_pinfo(struct mesh_ if (mpath->flags & MESH_PATH_RESOLVED) pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED; pinfo->hop_count = mpath->hop_count; @@ -94,27 +94,21 @@ Signed-off-by: P Praneesh #define MESH_FAST_TX_CACHE_MAX_SIZE 512 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c -@@ -504,7 +504,10 @@ static u32 hwmp_route_info_get(struct ie +@@ -504,7 +504,7 @@ static u32 hwmp_route_info_get(struct ie if (next_hop) ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); if (next_hop != sta) { - mpath->path_change_count++; + atomic_inc(&mpath->path_change_count); -+ mpath_dbg(sdata, "MESH MPU dst %pM next hop %pM" -+ " metric %d ft 0x%x\n", -+ mpath->dst, sta->deflink.addr, last_hop_metric, action); flush_mpath = true; } mesh_path_assign_nexthop(mpath, sta); -@@ -565,7 +568,10 @@ static u32 hwmp_route_info_get(struct ie +@@ -565,7 +565,7 @@ static u32 hwmp_route_info_get(struct ie if (next_hop) ether_addr_copy(old_next_hop_addr, next_hop->sta.addr); if (next_hop != sta) { - mpath->path_change_count++; + atomic_inc(&mpath->path_change_count); -+ mpath_dbg(sdata, "MESH MPU dst %pM next hop %pM" -+ " metric %d ft 0x%x\n", -+ mpath->dst, sta->deflink.addr, last_hop_metric, action); flush_mpath = true; } mesh_path_assign_nexthop(mpath, sta); diff --git a/package/kernel/mac80211/patches/nss/subsys/751-mac80211-Get-valid-last_rate-for-rx_bitrate-from-cpu.patch b/package/kernel/mac80211/patches/nss/subsys/751-mac80211-Get-valid-last_rate-for-rx_bitrate-from-cpu.patch new file mode 100644 index 0000000000..ea83021014 --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/751-mac80211-Get-valid-last_rate-for-rx_bitrate-from-cpu.patch @@ -0,0 +1,68 @@ +From eac6bea547505fc6545014755e8e529fd804df42 Mon Sep 17 00:00:00 2001 +From: Maharaja Kennadyrajan +Date: Tue, 18 Apr 2023 14:41:05 +0530 +Subject: [PATCH 1/3] mac80211: Get valid last_rate for rx_bitrate from cpu + stats + +Get the valid last_rate from the cpu rx_stats while filling the +rx_bitrate in the station dump. This helps to avoid the missing +rx bitrate field in the iw station dump. + +Signed-off-by: Tamizh Chelvam Raja +Signed-off-by: Maharaja Kennadyrajan +--- + net/mac80211/sta_info.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -2385,7 +2385,7 @@ void ieee80211_sta_update_pending_airtim + } + + static struct ieee80211_sta_rx_stats * +-sta_get_last_rx_stats(struct sta_info *sta) ++sta_get_last_rx_stats(struct sta_info *sta, bool is_rx_bitrate) + { + struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; + int cpu; +@@ -2398,8 +2398,13 @@ sta_get_last_rx_stats(struct sta_info *s + + for_each_possible_cpu(cpu) { + struct ieee80211_sta_rx_stats *cpustats; ++ u16 rate; + + cpustats = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); ++ rate = READ_ONCE(cpustats->last_rate); ++ ++ if(!cpustats->last_rx || (is_rx_bitrate && (rate == STA_STATS_RATE_INVALID))) ++ continue; + + if (time_after(cpustats->last_rx, stats->last_rx)) + stats = cpustats; +@@ -2476,7 +2481,7 @@ static void sta_stats_decode_rate(struct + + static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) + { +- u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate); ++ u32 rate = READ_ONCE(sta_get_last_rx_stats(sta, true)->last_rate); + + if (rate == STA_STATS_RATE_INVALID) + return -EINVAL; +@@ -2576,7 +2581,7 @@ void sta_set_sinfo(struct sta_info *sta, + int i, ac, cpu; + struct ieee80211_sta_rx_stats *last_rxstats; + +- last_rxstats = sta_get_last_rx_stats(sta); ++ last_rxstats = sta_get_last_rx_stats(sta, false); + + sinfo->generation = sdata->local->sta_generation; + +@@ -2859,7 +2864,7 @@ u32 sta_get_expected_throughput(struct s + + unsigned long ieee80211_sta_last_active(struct sta_info *sta) + { +- struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta); ++ struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta, false); + + if (!sta->deflink.status_stats.last_ack || + time_after(stats->last_rx, sta->deflink.status_stats.last_ack)) diff --git a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch b/package/kernel/mac80211/patches/nss/subsys/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch similarity index 74% rename from package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch rename to package/kernel/mac80211/patches/nss/subsys/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch index e5b4d7d9e7..6be28b6ac5 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch +++ b/package/kernel/mac80211/patches/nss/subsys/780-mac80211-Advertise-HW-checksum-offload-only-for-ethm.patch @@ -31,7 +31,7 @@ Signed-off-by: Tamizh Chelvam Raja static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, struct net_device *dev, struct sta_info *sta, struct ieee80211_key *key, struct sk_buff *skb, -@@ -3633,7 +3635,7 @@ ieee80211_sdata_netdev_features(struct i +@@ -3632,7 +3634,7 @@ ieee80211_sdata_netdev_features(struct i } static struct sk_buff * @@ -40,7 +40,7 @@ Signed-off-by: Tamizh Chelvam Raja { if (skb_is_gso(skb)) { struct sk_buff *segs; -@@ -3651,7 +3653,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *s +@@ -3650,7 +3652,7 @@ ieee80211_tx_skb_fixup(struct sk_buff *s if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) goto free; @@ -49,7 +49,7 @@ Signed-off-by: Tamizh Chelvam Raja int ofs = skb_checksum_start_offset(skb); if (skb->encapsulation) -@@ -3797,7 +3799,7 @@ static bool ieee80211_xmit_fast(struct i +@@ -3796,7 +3798,7 @@ static bool ieee80211_xmit_fast(struct i memcpy(ð, skb->data, ETH_HLEN - 2); /* after this point (skb is modified) we cannot return false */ @@ -58,7 +58,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return true; -@@ -4345,7 +4347,7 @@ void __ieee80211_subif_start_xmit(struct +@@ -4344,7 +4346,7 @@ void __ieee80211_subif_start_xmit(struct * things so we cannot really handle checksum or GSO offload. * fix it up in software before we handle anything else. */ @@ -67,15 +67,7 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) { len = 0; goto out; -@@ -4567,7 +4569,6 @@ netdev_tx_t ieee80211_subif_start_xmit(s - #ifdef CPTCFG_MAC80211_NSS_SUPPORT - ieee80211_xmit_nss_fixup(skb, dev); - #endif -- skb->fast_xmit = 0; - - if (likely(!is_multicast_ether_addr(eth->h_dest))) - goto normal; -@@ -4714,7 +4715,7 @@ static void ieee80211_8023_xmit(struct i +@@ -4715,7 +4717,7 @@ static void ieee80211_8023_xmit(struct i } } @@ -84,30 +76,9 @@ Signed-off-by: Tamizh Chelvam Raja if (!skb) return; -@@ -4839,6 +4840,7 @@ void ieee80211_8023_xmit_ap(struct ieee8 - netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb, - struct net_device *dev) - { -+#ifdef CPTCFG_MAC80211_SFE_SUPPORT - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_tx_control control = {}; -@@ -4873,9 +4875,10 @@ out: - } - - return NETDEV_TX_OK; -- } else { -- return __ieee80211_subif_start_xmit_8023(skb, dev, 0, 0, NULL); - } -+#endif -+ return __ieee80211_subif_start_xmit_8023(skb, dev, 0, 0, NULL); -+ - } - - netdev_tx_t __ieee80211_subif_start_xmit_8023(struct sk_buff *skb, --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -2250,6 +2250,10 @@ int ieee80211_if_add(struct ieee80211_lo +@@ -2267,6 +2267,10 @@ int ieee80211_if_add(struct ieee80211_lo ndev->features |= local->hw.netdev_features; ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; diff --git a/package/kernel/mac80211/patches/nss/subsys/785-wifi-mac80211-Add-mac-hw-flag-to-avoid-queue-skb.patch b/package/kernel/mac80211/patches/nss/subsys/785-wifi-mac80211-Add-mac-hw-flag-to-avoid-queue-skb.patch new file mode 100644 index 0000000000..c2846abf7e --- /dev/null +++ b/package/kernel/mac80211/patches/nss/subsys/785-wifi-mac80211-Add-mac-hw-flag-to-avoid-queue-skb.patch @@ -0,0 +1,342 @@ +From ca28b8b125c27063b9b4bc60bb85206ca8e0d403 Mon Sep 17 00:00:00 2001 +From: Yuvasree Sivasankaran +Date: Thu, 31 Aug 2023 10:59:33 +0530 +Subject: [PATCH] wifi: mac80211: Add mac hw flag to avoid queue skb + +Queue SKB in mac80211 become mandatory from latest 6.1 kernel. Because of +this queuing, there will be performance degradation. Add hw flag option +to enable tx queue in Driver/Hardware. + +Driver/hardware can register for HAS_TX_QUEUE HW flag and avoid tx queuing +in mac80211. + +Add same HW flag checks to avoid accessing skb queues which will be +NULL or invalid and also NULL checks for sta txqs for NULL or invalid +access. + +Signed-off-by: Yuvasree Sivasankaran +--- + include/net/mac80211.h | 1 + + net/mac80211/debugfs.c | 1 + + net/mac80211/tx.c | 18 ++++++++++++++---- + 4 files changed, 17 insertions(+), 4 deletions(-) + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2732,6 +2732,9 @@ struct ieee80211_txq { + * + * @IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD: Hardware suports tid calssification offload. + * ++ * @IEE80211_HW_HAS_TX_QUEUE: Hardware/drivers has tx queue, does skb queuing itself, ++ * the stack will not do tx queuing. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2792,6 +2795,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_SUPPORTS_NSS_OFFLOAD, + IEEE80211_HW_SUPPORTS_MESH_NSS_OFFLOAD, + IEEE80211_HW_SUPPORTS_TID_CLASS_OFFLOAD, ++ IEEE80211_HW_HAS_TX_QUEUE, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -508,6 +508,7 @@ static const char *hw_flag_names[] = { + FLAG(SUPPORTS_NSS_OFFLOAD), + FLAG(SUPPORTS_MESH_NSS_OFFLOAD), + FLAG(SUPPORTS_TID_CLASS_OFFLOAD), ++ FLAG(HAS_TX_QUEUE), + #undef FLAG + }; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1603,6 +1603,9 @@ int ieee80211_txq_setup_flows(struct iee + bool supp_vht = false; + enum nl80211_band band; + ++ if (ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) ++ return 0; ++ + ret = fq_init(fq, 4096); + if (ret) + return ret; +@@ -1650,6 +1653,9 @@ void ieee80211_txq_teardown_flows(struct + { + struct fq *fq = &local->fq; + ++ if (ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) ++ return; ++ + kfree(local->cvars); + local->cvars = NULL; + +@@ -1666,7 +1672,8 @@ static bool ieee80211_queue_skb(struct i + struct ieee80211_vif *vif; + struct txq_info *txqi; + +- if (sdata->vif.type == NL80211_IFTYPE_MONITOR) ++ if (ieee80211_hw_check(&local->hw, HAS_TX_QUEUE) || ++ sdata->vif.type == NL80211_IFTYPE_MONITOR) + return false; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) +@@ -4329,7 +4336,8 @@ void __ieee80211_subif_start_xmit(struct + } + } + +- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); ++ if (unlikely(!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE))) ++ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); + ieee80211_aggr_check(sdata, sta, skb); + + if (sta) { +@@ -4681,8 +4689,10 @@ static void ieee80211_8023_xmit(struct i + bool multicast; + u8 tid; + +- queue = ieee80211_select_queue(sdata, sta, skb); +- skb_set_queue_mapping(skb, queue); ++ if (unlikely(!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE))) { ++ queue = ieee80211_select_queue(sdata, sta, skb); ++ skb_set_queue_mapping(skb, queue); ++ } + + multicast = is_multicast_ether_addr(ra); + +@@ -6379,9 +6389,12 @@ int ieee80211_tx_control_port(struct wip + } + + if (!IS_ERR(sta)) { +- u16 queue = ieee80211_select_queue(sdata, sta, skb); + +- skb_set_queue_mapping(skb, queue); ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) { ++ u16 queue = ieee80211_select_queue(sdata, sta, skb); ++ ++ skb_set_queue_mapping(skb, queue); ++ } + + /* + * for MLO STA, the SA should be the AP MLD address, but +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4524,6 +4524,9 @@ static int ieee80211_get_txq_stats(struc + struct ieee80211_sub_if_data *sdata; + int ret = 0; + ++ if (ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) ++ return 1; ++ + spin_lock_bh(&local->fq.lock); + rcu_read_lock(); + +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -839,7 +839,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + atomic_set(&local->agg_queue_stop[i], 0); + } + tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending); +- tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); ++ ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) ++ tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); ++ + tasklet_setup(&local->tasklet, ieee80211_tasklet_handler); + + skb_queue_head_init(&local->skb_queue); +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1549,6 +1549,9 @@ static void sta_ps_start(struct sta_info + + ieee80211_clear_fast_xmit(sta); + ++ if (!sta->sta.txq[0]) ++ return; ++ + for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { + struct ieee80211_txq *txq = sta->sta.txq[tid]; + struct txq_info *txqi = to_txq_info(txq); +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -140,15 +140,17 @@ static void __cleanup_single_sta(struct + atomic_dec(&ps->num_sta_ps); + } + +- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { +- struct txq_info *txqi; ++ if (sta->sta.txq[0]) { ++ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { ++ struct txq_info *txqi; + +- if (!sta->sta.txq[i]) +- continue; ++ if (!sta->sta.txq[i]) ++ continue; + +- txqi = to_txq_info(sta->sta.txq[i]); ++ txqi = to_txq_info(sta->sta.txq[i]); + +- ieee80211_txq_purge(local, txqi); ++ ieee80211_txq_purge(local, txqi); ++ } + } + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +@@ -430,7 +432,9 @@ void sta_info_free(struct ieee80211_loca + + sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); + +- kfree(to_txq_info(sta->sta.txq[0])); ++ if (sta->sta.txq[0]) ++ kfree(to_txq_info(sta->sta.txq[0])); ++ + kfree(rcu_dereference_raw(sta->sta.rates)); + #ifdef CPTCFG_MAC80211_MESH + kfree(sta->mesh); +@@ -532,8 +536,6 @@ __sta_info_alloc(struct ieee80211_sub_if + struct ieee80211_local *local = sdata->local; + struct ieee80211_hw *hw = &local->hw; + struct sta_info *sta; +- void *txq_data; +- int size; + int i; + + sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); +@@ -611,18 +613,22 @@ __sta_info_alloc(struct ieee80211_sub_if + + sta->last_connected = ktime_get_seconds(); + +- size = sizeof(struct txq_info) + +- ALIGN(hw->txq_data_size, sizeof(void *)); + +- txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp); +- if (!txq_data) +- goto free; ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) { ++ void *txq_data; ++ int size = sizeof(struct txq_info) + ++ ALIGN(hw->txq_data_size, sizeof(void *)); ++ ++ txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp); ++ if (!txq_data) ++ goto free; + +- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { +- struct txq_info *txq = txq_data + i * size; ++ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { ++ struct txq_info *txq = txq_data + i * size; + +- /* might not do anything for the (bufferable) MMPDU TXQ */ +- ieee80211_txq_init(sdata, sta, txq, i); ++ /* might not do anything for the (bufferable) MMPDU TXQ */ ++ ieee80211_txq_init(sdata, sta, txq, i); ++ } + } + + if (sta_prepare_rate_control(local, sta, gfp)) +@@ -696,7 +702,8 @@ __sta_info_alloc(struct ieee80211_sub_if + return sta; + + free_txq: +- kfree(to_txq_info(sta->sta.txq[0])); ++ if (sta->sta.txq[0]) ++ kfree(to_txq_info(sta->sta.txq[0])); + free: + sta_info_free_link(&sta->deflink); + #ifdef CPTCFG_MAC80211_MESH +@@ -1691,11 +1698,13 @@ void ieee80211_sta_ps_deliver_wakeup(str + if (!ieee80211_hw_check(&local->hw, AP_LINK_PS)) + drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); + +- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { +- if (!sta->sta.txq[i] || !txq_has_queue(sta->sta.txq[i])) +- continue; ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) { ++ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { ++ if (!sta->sta.txq[i] || !txq_has_queue(sta->sta.txq[i])) ++ continue; + +- schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i])); ++ schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i])); ++ } + } + + skb_queue_head_init(&pending); +@@ -2110,6 +2119,9 @@ ieee80211_sta_ps_deliver_response(struct + * TIM recalculation. + */ + ++ if (!sta->sta.txq[0]) ++ return; ++ + for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { + if (!sta->sta.txq[tid] || + !(driver_release_tids & BIT(tid)) || +@@ -2546,7 +2558,7 @@ static void sta_set_tidstats(struct sta_ + tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; + } + +- if (tid < IEEE80211_NUM_TIDS) { ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE) && tid < IEEE80211_NUM_TIDS) { + spin_lock_bh(&local->fq.lock); + rcu_read_lock(); + +@@ -2874,6 +2886,9 @@ unsigned long ieee80211_sta_last_active( + + static void sta_update_codel_params(struct sta_info *sta, u32 thr) + { ++ if (ieee80211_hw_check(&sta->sdata->local->hw, HAS_TX_QUEUE)) ++ return; ++ + if (thr && thr < STA_SLOW_THRESHOLD * sta->local->num_sta) { + sta->cparams.target = MS2TIME(50); + sta->cparams.interval = MS2TIME(300); +--- a/net/mac80211/debugfs_sta.c ++++ b/net/mac80211/debugfs_sta.c +@@ -162,6 +162,9 @@ static ssize_t sta_aqm_read(struct file + bufsz + buf - p, + "tid ac backlog-bytes backlog-packets new-flows drops marks overlimit collisions tx-bytes tx-packets flags\n"); + ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) ++ goto skip_txq_info; ++ + for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { + if (!sta->sta.txq[i]) + continue; +@@ -186,6 +189,7 @@ static ssize_t sta_aqm_read(struct file + test_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) ? " DIRTY" : ""); + } + ++skip_txq_info: + rcu_read_unlock(); + spin_unlock_bh(&local->fq.lock); + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -832,7 +832,8 @@ bool ieee80211_mesh_xmit_fast(struct iee + if (!skb) + return true; + +- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); ++ if (unlikely(!ieee80211_hw_check(&sdata->local->hw, HAS_TX_QUEUE))) ++ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); + + meshhdr = (struct ieee80211s_hdr *)entry->hdr; + if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -477,10 +477,8 @@ static void __ieee80211_wake_queue(struc + * release someone's lock, but it is fine because all the callers of + * __ieee80211_wake_queue call it right before releasing the lock. + */ +- if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) ++ if (!ieee80211_hw_check(&local->hw, HAS_TX_QUEUE)) + tasklet_schedule(&local->wake_txqs_tasklet); +- else +- _ieee80211_wake_txqs(local, flags); + } + + void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, diff --git a/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch b/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch similarity index 92% rename from package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch rename to package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch index 7043ecb079..642901bed1 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/829-mac80211-fix-mesh-ping-issue.patch +++ b/package/kernel/mac80211/patches/nss/subsys/829-mac80211-fix-mesh-ping-issue.patch @@ -10,7 +10,7 @@ Signed-off-by: Aaradhana Sahu --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -4748,16 +4748,14 @@ void ieee80211_check_fast_rx(struct sta_ +@@ -4647,16 +4647,14 @@ void ieee80211_check_fast_rx(struct sta_ break; case NL80211_IFTYPE_MESH_POINT: @@ -31,7 +31,7 @@ Signed-off-by: Aaradhana Sahu default: goto clear; } -@@ -4980,10 +4978,7 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4878,10 +4876,7 @@ static bool ieee80211_invoke_fast_rx(str u8 sa[ETH_ALEN]; } addrs __aligned(2); struct ieee80211_sta_rx_stats *stats; @@ -42,7 +42,7 @@ Signed-off-by: Aaradhana Sahu /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write * to a common data structure; drivers can implement that per queue -@@ -5033,37 +5028,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4931,37 +4926,6 @@ static bool ieee80211_invoke_fast_rx(str snap_offs += IEEE80211_CCMP_HDR_LEN; } @@ -80,7 +80,7 @@ Signed-off-by: Aaradhana Sahu if (!ieee80211_vif_is_mesh(&rx->sdata->vif) && !(status->rx_flags & IEEE80211_RX_AMSDU)) { if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) -@@ -5101,30 +5065,6 @@ static bool ieee80211_invoke_fast_rx(str +@@ -4999,30 +4963,6 @@ static bool ieee80211_invoke_fast_rx(str return true; } diff --git a/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch b/package/kernel/mac80211/patches/nss/subsys/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch similarity index 89% rename from package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch rename to package/kernel/mac80211/patches/nss/subsys/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch index ea76cd9632..0f8289a892 100644 --- a/package/kernel/mac80211/patches/ath11k_nss/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch +++ b/package/kernel/mac80211/patches/nss/subsys/902-wifi-mac80211-Fix-memory-corruption-during-mesh-beac.patch @@ -25,7 +25,7 @@ Signed-off-by: Manish Dharanenthiran --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -683,7 +683,7 @@ struct ieee80211_if_mesh { +@@ -682,7 +682,7 @@ struct ieee80211_if_mesh { struct timer_list mesh_path_root_timer; unsigned long wrkq_flags; @@ -36,7 +36,7 @@ Signed-off-by: Manish Dharanenthiran --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c -@@ -1183,7 +1183,7 @@ void ieee80211_mbss_info_change_notify(s +@@ -1184,7 +1184,7 @@ void ieee80211_mbss_info_change_notify(s /* if we race with running work, worst case this work becomes a noop */ for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) @@ -45,7 +45,7 @@ Signed-off-by: Manish Dharanenthiran set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); } -@@ -1265,7 +1265,7 @@ void ieee80211_stop_mesh(struct ieee8021 +@@ -1266,7 +1266,7 @@ void ieee80211_stop_mesh(struct ieee8021 /* clear any mesh work (for next join) we may have accrued */ ifmsh->wrkq_flags = 0; @@ -54,7 +54,7 @@ Signed-off-by: Manish Dharanenthiran local->fif_other_bss--; atomic_dec(&local->iff_allmultis); -@@ -1732,9 +1732,9 @@ static void mesh_bss_info_changed(struct +@@ -1733,9 +1733,9 @@ static void mesh_bss_info_changed(struct u32 bit; u64 changed = 0;